Les Interfaces et les classes Abstraites confusion en Java avec des exemples

Je vais avoir du mal à comprendre quand utiliser une interface, par opposition à une classe abstraite, et vice-versa. Aussi, je suis confus quand pour étendre une interface avec une autre interface. Désolé pour le long post, mais c'est très déroutant.

Création de formes apparaît comme un point de départ populaire. Disons que nous voulons un moyen de modéliser les formes en 2D. Nous savons que chaque forme aura une zone. Quelle serait la différence entre les deux implémentations:

avec des interfaces:

public interface Shape {
    public double area();
}

public class Square implements Shape{
    private int length = 5;
    public Square(){...}

    public double area()
         return length * length;
    }
}

avec classe abstraite:

abstract class Shape {
    abstract public double area();
}

public class Square extends Shape {
    private length = 5;
    public Square(){...}

    public double area(){
        return length * length;
    }

Je comprends que les classes abstraites permet de définir des variables d'instance et vous permet de donner des implémentations de méthode alors qu'une interface ne peut pas faire ces choses. Mais dans ce cas, il semble que ces deux versions sont identiques. Donc, en utilisant tout est beau?

Mais maintenant, de dire que nous voulons décrire les différents types de triangles. Nous pouvons avoir une isocèle, aiguë, et des triangles rectangles. Pour moi, il est logique d'utiliser l'héritage de classe dans ce cas. En utilisant le 'EST-A' définition: un Triangle rectangle "EST-UN" Triangle. Un Triangle "EST-UN" de Forme. Aussi, une classe abstraite doit définir les comportements et les attributs qui sont communs dans toutes les sous-classes, donc c'est parfait:

avec classe abstraite

abstract Triangle extends Shape {
    private final int sides = 3;
}
class RightTriangle extends Triangle {
    private int base = 4;
    private int height = 5;

    public RightTriangle(){...}

    public double area() {
        return .5 * base * height
    }
}

Nous pouvons faire cela avec les interfaces ainsi, avec le Triangle et la Forme des interfaces. Cependant, contrairement à l'héritage de classe (en utilisant "EST-UN" de la relation de définir ce que devrait être une sous-classe), je ne suis pas sûr de savoir comment utiliser une interface. Je vois deux façons:

Première façon:

  public interface Triangle {
      public final int sides = 3;
  }
  public class RightTriangle implements Triangle, Shape {
      private int base = 4;
      private int height = 5;

      public RightTriangle(){}
      public double area(){
          return .5 * height * base;
      }
  }

Deuxième façon:

public interface Triangle extends Shape {
     public final int sides = 3;
} 
public class RightTriangle implements Triangle {
    ....

    public double area(){
         return .5 * height * base;
    }
}

Il me semble que ces deux façons de travailler. Mais quand souhaitez-vous utiliser une voie plutôt que l'autre? Et quels sont les avantages de l'utilisation d'interfaces sur les classes abstraites pour représenter les différents triangles? Même si nous compliqué la description d'une forme, en utilisant l'interface vs classe abstraite semblent encore l'équivalent.

Un élément essentiel à des interfaces est qu'il permet de définir des comportements qui peuvent être partagés entre les classes indépendantes. Donc une interface Pilotable serait présent dans les classes de l'Avion ainsi que des Oiseaux. Donc dans ce cas, il est clair qu'une approche de l'interface est préféré.

Aussi, à tirer parti de la confusion de l'interface de l'extension d'une autre interface:
Quand faut-il "EST-UN" de la relation être ignoré au moment de décider sur ce que devrait être une interface?
Prenez cet exemple: LIEN.

Pourquoi 'VeryBadVampire' être une classe et de "Vampire" être une interface? Un "VeryBadVampire" EST-UN "Vampire", si ma compréhension est qu'un "Vampire" doit être une super-classe (peut-être une classe abstraite). Un "Vampire" classe peut implémenter "Létales" à garder son létal de comportement. En outre, un "Vampire" EST-UN "Monstre", afin de "Monstre" devrait être une classe ainsi. Un "Vampire" classe peut implémenter une interface appelée "Dangereux" pour garder son comportement dangereux. Si nous voulons créer un nouveau monstre appelé "BigRat' qui est dangereux, mais ils ne sont pas mortels, alors nous pouvons créer un "BigRat' classe qui s'étend de "Monstre" et met en œuvre des "Dangereuses".

Ne serait pas au-dessus d'atteindre le même résultat que l'utilisation de "Vampire" comme une interface (décrit dans le lien)? La seule différence que je vois est que l'utilisation de l'héritage de classe et la préservation de l' "EST-UN" de la relation efface beaucoup de confusion. Pourtant, ce n'est pas suivie. Quel est l'avantage de faire cela?

Même si vous voulais un monstre à part vampirique comportement, il est toujours possible de redéfinir la façon dont les objets sont représentés. Si nous voulions un nouveau type de vampire, monstre appelé "VeryMildVampire" et nous avons voulu créer un vampire-comme monstre appelé "Chupacabra", nous pouvons le faire:

"Vampire" classe étend "Monstre" met en œuvre "Dangereux", "Létales", "BloodSuckable'

'VeryMildVampire' classe étend "Vampire" classe

'Chupacabra" class extends 'Monstre' implémente 'BloodSuckable'

Mais nous pouvons aussi le faire:

'VeryMildVampire" s'étend au "Monstre" met en œuvre Dangereux, Mortel, Vampirique

'Chupacabra" s'étend au "Monstre" met en œuvre Dangereux, Vampirique

La deuxième façon, ici, crée un " Vampirique de l'interface, de sorte que l'on peut le plus facilement définir une relative monstre plutôt que de créer un groupe d'interfaces qui définissent vampirique comportements (comme dans le premier exemple). Mais cela rompt la relation " EST-UN. Donc, je suis confus...

  • Vous ai expliqué le problème avec beaucoup de clarté. Apprécier l'effort 🙂
InformationsquelleAutor Carts | 2012-07-09