2010-05-15 4 views
7

Je lis le livre - Hadoop: The Definitive Guideinterface Java et l'émission classe abstraite

Dans le chapitre 2 (Page 25), il est mentionné « La nouvelle API privilégie classe abstraite sur les interfaces, puisque ceux-ci sont plus faciles à évoluer pour. Par exemple, vous pouvez ajouter une méthode (avec une implémentation par défaut) à une classe abstraite sans casser les anciennes implémentations de la classe ". Qu'est-ce que cela signifie (en particulier ce que signifie "briser les anciennes implémentations de la classe")? Apprécier si quelqu'un pourrait me montrer un échantillon pourquoi dans cette perspective la classe abstraite est meilleure que l'interface?

merci à l'avance, George

Répondre

10

Dans le cas d'une interface, toutes méthodes qui sont définies dans une interface doit être mis en œuvre par une classe qui implémente.

Compte tenu de l'interface A

interface A { 
    public void foo(); 
} 

et une classe B:

class B implements A { 
} 

il doit fournir une mise en oeuvre pour le procédé défini dans l'interface:

class B implements A { 
    @Override 
    public void foo() { 
     System.out.println("foo"); 
    } 
} 

Sinon, il s'agit d'une erreur de compilation. Maintenant, prenez une classe abstraite avec une implémentation par défaut d'une méthode:

abstract class C { 
    public void bar() { 
     System.out.println("bar"); 
    } 
} 

où une classe héritant de cette classe abstraite peut ressembler à ceci:

class D extends C { } 

sans erreur. Mais il peut également remplacer l'implémentation de la méthode par défaut s'il est enclin à le faire. Ce que disait l'auteur: Si votre API n'est pas encore stable et que vous avez besoin d'adapter les interfaces (oui, les classes abstraites sont aussi des interfaces (en OOP-speak)), alors une classe abstraite vous permet d'ajouter des choses sans casser les classes qui sont déjà là. Cependant, cela ne vaut que pour les méthodes non abstraites. Si vous ajoutez des méthodes abstraites, elles doivent toujours être implémentées dans chaque classe dérivée. Mais tout de même, cela peut vous rendre la vie plus facile si vous avez une API qui est en constante évolution et déjà beaucoup de choses qui se construisent dessus.

+0

Merci! Ce que je suis confus est cette déclaration - "casser les vieilles implémentations de la classe" dans le livre. "La classe" signifie que la classe dérive de la classe abstraite ou de la classe sur laquelle la classe abstraite est basée? – George2

+1

@George: Cela signifie la classe dérivée de l'ancienne version de la classe interface/abstract. Avec les interfaces, il n'est plus valide car il ne parvient pas à implémenter une méthode que vous avez ajoutée à l'interface. Avec des classes abstraites et des méthodes non abstraites, il peut simplement utiliser la mise en œuvre de la classe de base sans même savoir qu'elle est là. – Joey

+0

Merci! Vous voulez dire supposer dans la version 1, la classe abstraite a la méthode Foo et une classe dérive de la classe abstraite implémente Foo. Et dans la version 2 de la classe abstraite, une nouvelle méthode Goo est ajoutée, et la classe dérivée fonctionnera toujours sans être impactée (si Goo a une implémentation par défaut dans la classe abstraite)? – George2

6

Si vous ajoutez une méthode avec une implémentation par défaut à une classe abstraite, rien ne doit changer dans toutes les classes dérivées. Si vous ajoutez une méthode à une interface, toutes les classes implémentant cette interface doivent également implémenter la méthode, sinon elles ne seront pas compilées.

+0

Merci! "rien n'a besoin de changer dans les classes de base" - "toutes les classes de base", vous voulez dire la classe de base de la classe abstraite, ou la classe qui dérive de la classe abstraite? – George2

+1

Merde. J'aurais dû laisser ces exemples de côté. Il m'a fallu quatre minutes de plus ;-) – Joey

+0

Des réponses à mon commentaire ci-dessus? :-) – George2

1

S'il vous plaît se référer également aux directives suivantes de Eclipse Wiki

Evolving API Java

Adding an API method

Exemple 4 - Ajout d'une méthode API

peuvent ajouter une méthode API à une classe ou une interface rompre la compatibilité avec les clients existants?

Si la méthode est ajoutée à une interface que les clients peuvent implémenter, alors c'est définitivement un changement de rupture.

Si la méthode est ajoutée à une classe (interface) que les clients ne sont pas autorisés à mettre en sous-classe, alors il ne s'agit pas d'une modification de rupture.

Toutefois, si la méthode est ajoutée à une classe que les clients peuvent sous-classer, la modification doit normalement être considérée comme une modification de rupture. La raison de cette conclusion sévère est due à la possibilité que la sous-classe d'un client ait déjà sa propre implémentation d'une méthode par ce nom. L'ajout de la méthode API à la superclasse réduit le code du client, car ce serait une pure coïncidence si la méthode existante du client rencontrait le contrat API de la méthode nouvellement ajoutée. En pratique, si la probabilité d'une coïncidence de ce genre est suffisamment faible, ce type de changement est souvent traité comme s'il était non brisant.

Questions connexes