64 votes

Quelles sont les différences entre les classes abstraites et les interfaces en Java 8?

En Java il y a une subtile mais importante différence entre les classes abstraites et les interfaces des implémentations par défaut. Les classes abstraites pu les avoir, les interfaces ne pouvait pas. Java 8 bien que la présente implémentations par défaut pour les interfaces, ce qui signifie que ce n'est plus la différence fondamentale entre une interface et une classe abstraite.

Donc, c'est quoi?

Du mieux que je peux dire, la seule différence (à part peut-être quelques sous le capot de l'efficacité de trucs), c'est que les classes abstraites suivre Java traditionnelle unique de l'héritage, alors que les interfaces peuvent avoir de multiples-l'héritage (ou plusieurs de mise en œuvre si vous voulez). Cela m'amène à une autre question -

Comment le nouveau Java 8 interfaces éviter le diamant Problème?

68voto

skiwi Points 8321

Les Interfaces ne peuvent pas avoir d'état qui leur sont associés.

Les classes abstraites peuvent avoir l'état associé avec eux.

En outre, les méthodes par défaut dans les interfaces n'ont pas besoin d'être mis en œuvre. Donc, dans cette façon, il ne se cassera pas déjà le code existant, en tant que bien que l'interface ne recevoir une mise à jour, la mise en œuvre de la classe n'a pas besoin de la mettre en œuvre.
Comme un résultat, vous pouvez obtenir des sous-optimale de code, mais si vous voulez avoir plus d'un code optimal, votre travail consiste à remplacer la valeur par défaut de mise en œuvre.

Et enfin, dans le cas d'un diamant problème se produit, alors le compilateur va vous avertir, et vous aurez besoin de choisir l'interface que vous souhaitez mettre en place.

Pour afficher plus au sujet de la diamond problème, considérons le code suivant:

interface A {
    void method();
}

interface B extends A {
    @Override
    default void method() {
        System.out.println("B");
    }
}

interface C extends A { 
    @Override
    default void method() {
        System.out.println("C");
    }
}

interface D extends B, C {

}

Ici, je reçois l'erreur de compilation sur interface D extends B, C, que:

interface D inherits unrelated defaults for method() form types B and C

La solution est:

interface D extends B, C {
    @Override
    default void method() {
        B.super.method();
    }
}

Dans le cas où j'ai voulu hériter de la method() de B.
La même chose vaut pour s' D ont un class.

Pour montrer encore plus sur la différence entre les interfaces et les classes abstraites dans Java 8, considérez les points suivants Team:

interface Player {

}

interface Team {
    void addPlayer(Player player);
}

Vous pouvez, en théorie, fournir une implémentation par défaut de addPlayer de telle sorte que vous pouvez ajouter des joueurs à par exemple une liste de joueurs.
Mais attendez...?
Comment dois-je stocker la liste des joueurs?
La réponse est que vous ne pouvez pas faire cela dans une interface, même si vous avez des implémentations par défaut disponibles.

17voto

Marco13 Points 14743

Il y a eu quelques très détaillée des réponses, mais ils semblent être absent un moment que j'ai au moins considérer comme l'un des très rares justifications d'avoir des classes abstraites à tous:

Les classes abstraites peuvent avoir protégé les membres (et les membres de la visibilité par défaut). Méthodes dans les interfaces sont implicitement public.

8voto

nosid Points 20267

La définition de la diamond problème est vague. Il y a toutes sortes de problèmes qui peuvent se produire avec l'héritage multiple. Heureusement, la plupart d'entre eux peuvent être facilement détectés au moment de la compilation, et les langages de programmation support des solutions simples pour contourner ces problèmes. La plupart de ces problèmes ne sont même pas spécifiques à l' diamant problème. Par exemple, un conflit de définitions de méthodes peuvent également se produire sans diamants:

interface Bar {
    default int test() { return 42; }
}
interface Baz {
    default int test() { return 6 * 9; }
}
class Foo implements Bar, Baz { }

Le problème spécifique avec les diamants est la question de inclusif vs exclusif. Si vous avez un type de hiérarchie où B et C de dériver à partir de Un, et D dérive de B et de C, alors la question est:

  • est D une B *et* C (c'est à dire un type de l' Un), ou
  • est D une B *ou* C (c'est à dire, deux types de Un).

Eh bien, dans Java 8 le type Un a une interface. Donc, il ne fait aucune différence, parce que les interfaces n'ont aucun état. Il n'a pas d'importance, que les interfaces peuvent définir des méthodes par défaut, car ils n'ont aucun état. Ils peuvent invoquer des méthodes qui ont un accès direct à l'état. Cependant, ces méthodes sont toujours mis en œuvre en fonction de l'héritage simple.

5voto

Philipp Points 22441

Maintenant que les interfaces peuvent contenir du code exécutable, beaucoup de cas d'utilisation pour les classes abstraites sont pris en charge par les interfaces. Mais les classes abstraites peuvent encore avoir des variables de membres, tandis que les interfaces ne peuvent pas.

Le diamant problème est évitée simplement en ne permettant pas qu'une classe implémente deux interfaces lorsque les deux interfaces de fournir une implémentation par défaut pour la même méthode avec la même signature.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X