web-dev-qa-db-fra.com

Java 8: méthodes d'extension virtuelle vs classe abstraite

Je regarde les nouvelles méthodes d'extension virtuelle dans les interfaces Java 8:

public interface MyInterface {
   default String myMethod() { 
      return "myImplementation"; 
   }
}

Je comprends leur objectif en permettant à une interface d'évoluer avec le temps et au bit d'héritage multiple, mais ils ont terriblement l'air d'une classe abstraite pour moi.

Si vous faites un nouveau travail, préférez-vous les classes abstraites aux méthodes d'extension pour implémenter une "interface" ou ces deux approches sont-elles théoriquement équivalentes?

28
Kong

L'un des principaux objectifs de ces constructions est de préserver la compatibilité avec les versions antérieures. L'ajout de fermetures au langage Java constitue une modification assez importante et il faut mettre à jour les choses pour en tirer pleinement parti. Par exemple, CollectionNAME_ in Java 8 utilisera des méthodes telles que forEach() qui fonctionnent conjointement avec lambdas. Ajouter simplement de telles méthodes à l'interface Collectionpréexistante ne serait pas réalisable, car cela annulerait la compatibilité avec les versions antérieures. Une classe que j’ai écrite en Java 7 et implémentant Collectionne compilerait plus car elle ne disposerait pas de ces méthodes. Par conséquent, ces méthodes sont introduites avec une implémentation "par défaut". Si vous connaissez Scala, vous pouvez voir que Java interfacename__s ressemble davantage à Scala traitname__s.

En ce qui concerne les interfaces et les classes abstraites, les deux sont toujours différent en Java 8; vous ne pouvez toujours pas avoir de constructeur dans une interface, par exemple. Par conséquent, les deux approches ne sont pas "conceptuellement équivalentes" en soi. Les classes abstraites sont plus structurées et peuvent être associées à un état, contrairement aux interfaces. Vous devriez utiliser ce qui convient le mieux dans le contexte de votre programme, comme vous le feriez avec Java 7 et les versions ultérieures.

31
arshajii
  1. Les classes abstraites ne peuvent pas être des classes racines d'expressions lambda, alors que interfaces avec des méthodes d'extension virtuelles peuvent l'être. 
  2. Les classes abstraites peuvent avoir des constructeurs et des variables membres, contrairement aux interfaces. Je crois que c’est l’exécution d’un constructeur possible et le lancement possible d’une exception vérifiée qui interdit aux classes abstraites d’être la racine d’une expression lambda.

Si vous souhaitez écrire une API permettant à l'utilisateur d'utiliser des expressions lambda, utilisez plutôt des interfaces.

5
aepurniet

Classes abstraites Etat de maintien (champs d'instance), afin de fournir un comportement commun (méthodes).
Vous ne voyez généralement pas (jamais?) Une classe abstraite sans état. 

Interfaces spécifiez les fonctionnalités . Ils sont censés déclarer le comportement comme un contrat et non le mettre en œuvre.
Ainsi, toutes les méthodes spécifiées dans le cadre d’une interface sont des méthodes "auxiliaires" - elles n’affectent pas la mise en oeuvre.

5
Mehrdad

Classes abstraites scores sur Java-8 interfaces dans les zones situées en dessous.

  1. Avec les classes abstraites, vous pouvez déclarer des champs qui sontnon statiques et finaux, et définir des méthodes concrètes publiques, protégées et privées. Avec les interfaces, tous les champs sont automatiquement publics, statiques et finaux, et toutes les méthodes que vous déclarez ou définissez (en tant que méthodes par défaut) sont publiques

  2. état mutablepeut être partagé/modifié avec des classes enfant contrairement à l'interface qui n'a que des constantes

  3. La classe abstraite peut être utilisée pour implémenter Template_method_pattern : Elle définit le squelette de programme d'un algorithme dans une opération, en reportant certaines étapes à des sous-classes.
  4. La classe abstraite peut être utilisée pour implémenter Decorator_pattern : un modèle de conception qui permet d’ajouter un comportement à un objet individuel, de manière statique ou dynamique, sans affecter le comportement d’autres objets de la même classe.
0
Ravindra babu