833 votes

L’interface de classe de Base de vs

Quand dois-je utiliser une interface et quand dois-je utiliser une classe de base ?

Faut-il toujours une interface si je ne veux pas réellement définir une implémentation de base des méthodes ?

Si j’ai une classe de chiens et de chats. Pourquoi voudrais-je à mettre en œuvre IPet au lieu de PetBase ? Je peux comprendre vu les interfaces pour ISheds ou IBarks (IMakesNoise ?), parce que ceux qui peuvent être placés sur une base par un animal, mais je ne comprends pas qui à utiliser pour un animal de compagnie générique.

543voto

Jon Limjap Points 46429

Prenons l'exemple d'un Chien et d'un Chat de la classe, et illustrons à l'aide de C#:

À la fois un chien et un chat sont des animaux, plus précisément, quadrupède mammifères (animaux sont waaay trop général). Supposons que vous avez un résumé de la classe des Mammifères, pour deux d'entre eux:

public abstract class Mammal

Cette classe de base aura probablement par défaut des méthodes telles que:

  • Alimentation
  • Mate

Qui sont tous des comportements qui ont plus ou moins la même mise en œuvre entre les deux espèces. Pour définir cela, vous devrez:

public class Dog : Mammal
public class Cat : Mammal

Maintenant, supposons qu'il existe d'autres mammifères, dont nous avons l'habitude de voir dans un zoo:

public class Giraffe : Mammal
public class Rhinoceros : Mammal
public class Hippopotamus : Mammal

Ce sera toujours valide car au cœur de la fonctionnalité, de la Chasse(), Alimentation() et Mate() sera toujours le même.

Cependant, les girafes, les rhinocéros et les hippopotames ne sont pas exactement les animaux que vous pouvez faire des animaux de compagnie. C'est là une interface sera utile:

public interface IPettable
{
    IList<Trick> Tricks{get; set;}
    void Bathe();
    void Train(Trick t);
}

La mise en œuvre du contrat ci-dessus ne sera pas la même entre un chat et un chien; de mettre leur mise en œuvre dans une classe abstraite pour hériter sera une mauvaise idée.

Votre Chien et de Chat, les définitions devraient ressembler à ça:

public class Dog : Mammal, IPettable
public class Cat : Mammal, IPettable

Théoriquement, vous pouvez les écraser à la hausse de la classe de base, mais essentiellement une interface vous permet d'ajouter uniquement sur les choses dont vous avez besoin dans une classe sans la nécessité de l'héritage.

Par conséquent, parce que d'habitude on hérite d'une classe abstraite (dans la plupart des langages à objets à typage statique qui est... a des exceptions, notamment C++), mais être en mesure d'implémenter plusieurs interfaces, il vous permet de construire des objets strictement requis .

155voto

Marcio Aguiar Points 6715

Eh bien, Josh Bloch a dit lui-même dans Efficace Java 2d:

Préférez les interfaces sur les classes abstraites

Quelques points principaux:

  • Classes existantes peuvent être aisément adaptés à mettre en œuvre un nouveau de l'interface. Tout ce que vous avez à faire est d'ajouter les méthodes requises, si ce n'est pas encore existent et ajouter un met en œuvre la clause de la déclaration de classe.

  • Les Interfaces sont idéales pour la définition de mixin. Grosso modo, un mixin est un type qu'une classe peut mettre en œuvre, en plus de son "principal type" pour déclarer qu'il fournit certains comportement en option. Par exemple, Comparable est un mixin interface permet à une catégorie à déclarer que son les instances sont commandés à l'égard de d'autres mutuellement objets comparables.

  • Les Interfaces permettent la construction de type non hiérarchique les cadres. Type de hiérarchies sont idéal pour l'organisation de certaines choses, mais d'autres choses ne tombent pas facilement dans une hiérarchie rigide.

  • Interfaces permettent coffre-fort, puissant améliorations de fonctionnalités via le récapitulatif par classe idiome. Si vous utilisez les classes abstraites pour définir des types, vous laisser le programmeur qui veut ajouter la fonctionnalité avec aucune autre alternative pour utiliser l'héritage.

En outre, vous pouvez combiner les vertus les interfaces et les classes abstraites par fournir un résumé du squelette la mise en œuvre de la classe pour aller avec chaque non triviaux de l'interface que vous exportez.

D'autre part, les interfaces sont très difficiles à faire évoluer. Si vous ajouter une méthode à une interface, il va casser tous ses implémentations.

PS.: Acheter le livre. C'est beaucoup plus détaillé.

143voto

Thomas Danecker Points 3127

Les Interfaces et les classes de base représentent deux différentes formes de relations.

L'héritage (classes de base) représentent un "est-un" de la relation. E. g. un chien ou un chat "est-un" animal de compagnie. Cette relation représente toujours le (seul) but de la classe (en collaboration avec le "principe de responsabilité unique").

Interfaces, d'autre part, représentent des fonctionnalités supplémentaires d'une classe. J'appellerais cela un "est" de la relation, comme dans "Foo est jetable", d'où l' IDisposable interface en C#.

113voto

Jason Cohen Points 36475

Style moderne consiste à définir l’IPet et PetBase.

L’avantage de l’interface, c’est que tout autre code peut l’utiliser sans aucun liens quelle qu’elle soit à un autre code exécutable. Complètement « propre ». Interfaces peuvent également être mélangés.

Mais les classes de base sont utiles pour des implémentations simples et utilitaires communs. Ainsi fournir une classe de base abstraite pour économiser du temps et code.

62voto

Kilhoffer Points 13430

En général, vous devriez favoriser les interfaces sur les classes abstraites. L'une des raisons pour utiliser une classe abstraite est si vous avez de la commune de mise en œuvre parmi les classes concrètes. Bien sûr, vous devez toujours déclarer une interface (IPet) et ont une classe abstraite (PetBase) à implémenter cette interface.À l'aide de petits interfaces distinctes, vous pouvez utiliser des multiples pour améliorer davantage de flexibilité. Les Interfaces permettent un maximum de flexibilité et de portabilité des types à travers les frontières. Lors du passage de références à travers les frontières, toujours passer l'interface et non pas le type de béton. Cela permet à l'extrémité de réception afin de déterminer la mise en œuvre concrète et offre un maximum de flexibilité. C'est absolument vrai lors de la programmation dans un système TDD/BDD de la mode.

La bande des Quatre a déclaré, dans leur livre "en Raison de l'héritage expose une sous-classe pour les détails de l'un de ses parents de la mise en œuvre, il est souvent dit que "l'héritage des pauses encapsulation". Je crois que cela est vrai.

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