36 votes

Pourquoi les interfaces sont-elles préférées aux classes abstraites ?

Récemment, j'ai assisté à un entretien et on m'a posé la question "Pourquoi les Interfaces sont-elles préférées aux classes abstraites?"

J'ai essayé de donner quelques réponses comme:

  • Nous pouvons obtenir uniquement une fonctionnalité d'extension
  • Elles sont 100% abstraites
  • L'implémentation n'est pas codée en dur

On m'a demandé de prendre n'importe quelle API JDBC que j'utilise. "Pourquoi sont-elles des Interfaces?".

Puis-je obtenir une meilleure réponse pour cela?

55voto

DevinB Points 5960

Cette question d'entretien reflète une certaine croyance de la personne qui pose la question. Je crois que cette personne a tort, et donc vous pouvez aller dans l'une des deux directions.

  1. Donnez-leur la réponse qu'ils veulent.
  2. Désaccordez de manière respectueuse.

La réponse qu'ils veulent, eh bien, les autres contributeurs l'ont très bien soulignée. L'héritage d'interface multiple, l'héritage oblige la classe à faire des choix d'implémentation, les interfaces peuvent être modifiées plus facilement.

Cependant, si vous créez un argument convaincant (et correct) dans votre désaccord, alors l'intervieweur pourrait prendre note. Tout d'abord, mettez en avant les aspects positifs des interfaces, c'est UNE OBLIGATION. Deuxièmement, je dirais que les interfaces sont meilleures dans de nombreux scénarios, mais elles entraînent également une duplication de code qui est une chose négative. Si vous avez une large gamme de sous-classes qui feront largement la même implémentation, plus des fonctionnalités supplémentaires, alors vous voudrez peut-être une classe abstraite. Cela vous permet d'avoir de nombreux objets similaires avec des détails fins, alors qu'avec seulement des interfaces, vous devez avoir de nombreux objets distincts avec un code presque identique.

Les interfaces ont de nombreuses utilisations et il y a une raison convaincante de croire qu'elles sont 'meilleures'. Cependant, vous devez toujours utiliser le bon outil pour le travail, et cela signifie que vous ne pouvez pas ignorer les classes abstraites.

24voto

TofuBeer Points 32441

En général, et ce n'est en aucun cas une "règle" qui devrait être suivie aveuglément, l'arrangement le plus flexible est :

interface
   classe abstraite
       classe concrète 1       
       classe concrète 2

L'interface est là pour quelques raisons :

  • une classe existante qui étend déjà quelque chose peut implémenter l'interface (en supposant que vous avez le contrôle sur le code de la classe existante)
  • une classe existante peut être sous-classe et la sous-classe peut implémenter l'interface (en supposant que la classe existante est subclassable)

Cela signifie que vous pouvez prendre des classes préexistantes (ou simplement des classes qui DOIVENT étendre quelque chose d'autre) et les faire fonctionner avec votre code.

La classe abstraite est là pour fournir tous les éléments communs aux classes concrètes. La classe abstraite est étendue lorsque vous écrivez de nouvelles classes ou modifiez des classes que vous voulez étendre (en supposant qu'elles étendent java.lang.Object).

Vous devriez toujours (à moins d'avoir une très bonne raison de ne pas le faire) déclarer les variables (d'instance, de classe, locales et les paramètres des méthodes) comme l'interface.

23voto

Joel Coehoorn Points 190579

Vous n'avez qu'une seule chance en matière d'héritage. Si vous créez une classe abstraite au lieu d'une interface, celui qui hérite de votre classe ne pourra pas hériter également d'une autre classe abstraite différente.

10voto

Rowland Shaw Points 22860

Vous pouvez implémenter plus d'une interface, mais vous ne pouvez hériter que d'une seule classe

10voto

Warrior Points 13394

Classes Abstraites

1. Ne peut pas être instanciée indépendamment de ses classes dérivées. Les constructeurs des classes abstraites sont appelés uniquement par leurs classes dérivées.

2. Définissent des signatures de membres abstraites que les classes de base doivent implémenter.

3. Sont plus extensibles que les interfaces, sans rompre la compatibilité de version. Avec les classes abstraites, il est possible d'ajouter des membres non abstraits supplémentaires que toutes les classes dérivées peuvent hériter.

4. Peut inclure des données stockées dans des champs.

5. Permettent d'avoir des membres (virtuels) avec une implémentation et, par conséquent, fournissent une implémentation par défaut d'un membre à la classe dérivée.

6. Dériver d'une classe abstraite utilise l'unique option de classe de base d'une sous-classe.

Interface

1. Ne peut pas être instanciée.

2. L'implémentation de tous les membres de l'interface se fait dans la classe de base. Il n'est pas possible d'implémenter seulement certains membres dans la classe d'implémentation.

3. Étendre les interfaces avec des membres supplémentaires rompt la compatibilité de version.

4. Ne peut stocker aucune donnée. Les champs peuvent être spécifiés uniquement dans les classes dérivées. La solution de contournement consiste à définir des propriétés, mais sans implémentation.

5. Tous les membres sont automatiquement virtuels et ne peuvent inclure aucune implémentation.

6. Bien qu'aucune implémentation par défaut ne puisse apparaître, les classes implémentant des interfaces peuvent continuer à dériver les unes des autres.

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