J'ai récemment eu deux entretiens téléphoniques où j'ai été interrogé sur les différences entre une interface et une classe abstraite. Je leur ai expliqué tous les aspects auxquels je pouvais penser, mais il semble qu'ils attendent que je mentionne quelque chose de spécifique, et je ne sais pas ce que c'est.
D'après mon expérience, je pense que ce qui suit est vrai. Si je manque un point important, faites-le moi savoir.
Interface:
Chaque méthode déclarée dans une interface devra être implémentée dans la sous-classe. Seuls les événements, les délégués, les propriétés (C #) et les méthodes peuvent exister dans une interface. Une classe peut implémenter plusieurs interfaces.
Classe abstraite:
Seules les méthodes abstraites doivent être implémentées par la sous-classe. Une classe abstraite peut avoir des méthodes normales avec des implémentations. La classe abstraite peut également avoir des variables de classe à côté des événements, des délégués, des propriétés et des méthodes. Une classe ne peut implémenter qu'une seule classe abstraite uniquement en raison de la non-existence de l'héritage multiple en C #.
Après tout cela, l'intervieweur a posé la question "Et si vous aviez une classe abstraite avec uniquement des méthodes abstraites? En quoi cela serait-il différent d'une interface?" Je ne connaissais pas la réponse mais je pense que c'est l'héritage comme mentionné ci-dessus, n'est-ce pas?
Un autre intervieweur m'a demandé si si vous aviez une variable publique à l'intérieur de l'interface, en quoi cela serait-il différent de celui de la classe abstraite? J'ai insisté sur le fait que vous ne pouvez pas avoir de variable publique dans une interface. Je ne savais pas ce qu'il voulait entendre mais il n'était pas satisfait non plus.
Voir aussi :
la source
I insisted you can't have a public variable inside an interface.
Je pense que l'interface peut avoir une variable publique. En fait, les variables dans l'interface sont automatiquement publiques et définitives.Réponses:
Bien que votre question indique que c'est pour "OO général", elle semble vraiment se concentrer sur l'utilisation .NET de ces termes.
En .NET (similaire pour Java):
En termes généraux OO, les différences ne sont pas nécessairement bien définies. Par exemple, il y a des programmeurs C ++ qui peuvent contenir des définitions rigides similaires (les interfaces sont un sous-ensemble strict de classes abstraites qui ne peuvent pas contenir d'implémentation), tandis que certains peuvent dire qu'une classe abstraite avec certaines implémentations par défaut est toujours une interface ou qu'une non-abstraite La classe peut toujours définir une interface.
En effet, il existe un idiome C ++ appelé NVI (Non-Virtual Interface) où les méthodes publiques sont des méthodes non virtuelles qui se «rapprochent» des méthodes virtuelles privées:
la source
Que diriez-vous d'une analogie: quand j'étais dans l'Air Force, je suis allé à la formation de pilote et je suis devenu pilote de l'USAF (US Air Force). À ce moment-là, je n'étais pas qualifié pour piloter quoi que ce soit et j'ai dû suivre une formation sur le type d'avion. Une fois diplômé, j'étais pilote (classe abstraite) et pilote C-141 (classe béton). À l'une de mes affectations, on m'a confié une tâche supplémentaire: agent de sécurité. Maintenant, j'étais toujours pilote et pilote C-141, mais j'exerçais également des fonctions d'agent de sécurité (j'ai mis en place ISafetyOfficer, pour ainsi dire). Un pilote n'était pas tenu d'être un agent de sécurité, d'autres personnes auraient pu le faire également.
Tous les pilotes de l'USAF doivent suivre certaines réglementations applicables à l'ensemble de l'Air Force, et tous les pilotes de C-141 (ou F-16 ou T-38) sont des pilotes de l'USAF. N'importe qui peut être agent de sécurité. Donc, pour résumer:
note ajoutée: cela devait être une analogie pour aider à expliquer le concept, pas une recommandation de codage. Voir les différents commentaires ci-dessous, la discussion est intéressante.
la source
Jay
ne peut pas hériter de plusieurs classes (pilote C-141, pilote F-16 et pilote T-38), cela signifie-t-il que les classes devraient devenir des interfaces? MerciJe pense que la réponse qu'ils recherchent est la différence philosophique fondamentale ou OPPS.
L'héritage de classe abstraite est utilisé lorsque la classe dérivée partage les propriétés principales et le comportement de la classe abstraite. Le type de comportement qui définit réellement la classe.
D'autre part, l'héritage d'interface est utilisé lorsque les classes partagent un comportement périphérique, celles qui ne définissent pas nécessairement la classe dérivée.
Par exemple. Une voiture et un camion partagent beaucoup de propriétés de base et le comportement d'une classe abstraite automobile, mais ils partagent également certains comportements périphériques comme générer des gaz d'échappement que même les classes non automobiles comme les foreurs ou les générateurs de puissance partagent et ne définissent pas nécessairement une voiture ou un camion , donc Car, Truck, Driller et PowerGenerator peuvent tous partager la même interface IExhaust.
la source
accelerate
fait partie du comportement de base de la classe abstraite Automobile, alors je ne peux pas dire que celaaccelerate
montre la nature du contrat . qu'est-ce que la nature du contrat? pourquoi ce mot estcontract
introduit chaque fois que nous parlonsinterface
?interface
doit avoir un comportement périphérique, alors pourquoipublic interface List<E> extends Collection<E> {}
est conçu pour décrire le comportement de base delist
? cela contredit en fait la réponse de Prasun. Les deuxCollection<E>
etList<E>
sont des interfaces ici.En bref: les classes abstraites sont utilisées pour la modélisation une hiérarchie de classes de classes similaires (par exemple, Animal peut être une classe abstraite et Human, Lion, Tiger peut être une classe dérivée concrète)
ET
L'interface est utilisée pour la communication entre 2 classes similaires / non similaires qui ne se soucient pas du type de la classe implémentant l'interface (par exemple, la hauteur peut être une propriété d'interface et elle peut être implémentée par Human, Building, Tree. Peu importe si vous pouvez manger , vous pouvez nager, vous pouvez mourir ou quoi que ce soit .. cela importe seulement une chose dont vous avez besoin pour avoir la hauteur (mise en œuvre dans votre classe)).
la source
Il y a quelques autres différences -
Les interfaces ne peuvent pas avoir d'implémentations concrètes. Les classes de base abstraites peuvent. Cela vous permet de fournir des implémentations concrètes. Cela peut permettre à une classe de base abstraite de fournir un contrat plus rigoureux, alors qu'une interface ne décrit vraiment que la façon dont une classe est utilisée. (La classe de base abstraite peut avoir des membres non virtuels définissant le comportement, ce qui donne plus de contrôle à l'auteur de la classe de base.)
Plusieurs interfaces peuvent être implémentées sur une classe. Une classe ne peut dériver que d'une seule classe de base abstraite. Cela permet une hiérarchie polymorphe à l'aide d'interfaces, mais pas de classes de base abstraites. Cela permet également un pseudo-multi-héritage à l'aide d'interfaces.
Les classes de base abstraites peuvent être modifiées dans v2 + sans casser l'API. Les modifications apportées aux interfaces interrompent les modifications.
[C # /. NET Specific] Les interfaces, à la différence des classes de base abstraites, peuvent être appliquées aux types de valeur (structures). Les structures ne peuvent pas hériter des classes de base abstraites. Cela permet d'appliquer des contrats de comportement / directives d'utilisation aux types de valeur.
la source
Héritage
Considérez une voiture et un bus. Ce sont deux véhicules différents. Mais encore, ils partagent certaines propriétés communes comme ils ont une direction, des freins, des engrenages, un moteur, etc.
Donc, avec le concept d'héritage, cela peut être représenté comme suit ...
Maintenant un vélo ...
Et une voiture ...
C'est tout sur l' héritage . Nous les utilisons pour classer les objets dans des formes de base plus simples et leurs enfants comme nous l'avons vu ci-dessus.
Classes abstraites
Les classes abstraites sont des objets incomplets . Pour mieux comprendre, considérons à nouveau l'analogie avec le véhicule.
Un véhicule peut être conduit. Droite? Mais différents véhicules sont conduits de différentes manières ... Par exemple, vous ne pouvez pas conduire une voiture comme vous conduisez un vélo.
Alors, comment représenter la fonction de conduite d'un véhicule? Il est plus difficile de vérifier de quel type de véhicule il s'agit et de le conduire avec sa propre fonction; vous devrez changer la classe Driver encore et encore lors de l'ajout d'un nouveau type de véhicule.
Voici le rôle des classes et méthodes abstraites. Vous pouvez définir la méthode de lecteur comme abstraite pour indiquer que tous les enfants hérités doivent implémenter cette fonction.
Donc, si vous modifiez la classe du véhicule ...
Le vélo et la voiture doivent également spécifier comment le conduire. Sinon, le code ne se compilera pas et une erreur est générée.
En bref .. une classe abstraite est une classe partiellement incomplète avec des fonctions incomplètes, que les enfants héritiers doivent spécifier les leurs.
Interfaces Les interfaces sont totalement incomplètes. Ils n'ont aucune propriété. Ils indiquent simplement que les enfants héritiers sont capables de faire quelque chose ...
Supposons que vous ayez différents types de téléphones portables avec vous. Chacun d'eux a différentes façons de remplir différentes fonctions; Ex: appeler une personne. Le fabricant du téléphone précise comment le faire. Ici, les téléphones mobiles peuvent composer un numéro - c'est-à-dire qu'il est capable de composer. Représentons cela comme une interface.
Ici, le fabricant du Dialable définit comment composer un numéro. Il vous suffit de lui donner un numéro à composer.
En utilisant des interfaces au lieu de classes abstraites, l'auteur de la fonction qui utilise un Dialable n'a pas à se soucier de ses propriétés. Ex: a-t-il un écran tactile ou un pavé numérique, s'agit-il d'un téléphone fixe ou d'un téléphone portable. Vous avez juste besoin de savoir s'il est numérotable; hérite-t-il (ou implémente-t-il) l'interface Dialable?
Et plus important encore , si un jour vous changez le Dialable avec un autre
Vous pouvez être sûr que le code fonctionne toujours parfaitement car la fonction qui utilise le dialable ne dépend pas (et ne peut pas) dépendre de détails autres que ceux spécifiés dans l'interface Dialable. Ils implémentent tous les deux une interface Dialable et c'est la seule chose dont la fonction se soucie.
Les interfaces sont couramment utilisées par les développeurs pour garantir l'interopérabilité (à utiliser de manière interchangeable) entre les objets, dans la mesure où ils partagent une fonction commune (tout comme vous pouvez passer à une ligne fixe ou à un téléphone mobile, dans la mesure où vous n'avez qu'à composer un numéro). En bref, les interfaces sont une version beaucoup plus simple des classes abstraites, sans aucune propriété.
Notez également que vous pouvez implémenter (hériter) autant d'interfaces que vous le souhaitez mais vous ne pouvez étendre (hériter) qu'une seule classe parent.
Plus d'informations Classes abstraites vs interfaces
la source
Si vous considérez
java
comme un langage OOP pour répondre à cette question, la version Java 8 rend obsolète une partie du contenu des réponses ci-dessus. L'interface java peut maintenant avoir des méthodes par défaut avec une implémentation concrète.Le site Web Oracle fournit les principales différences entre
interface
et laabstract
classe.Envisagez d'utiliser des classes abstraites si:
Envisagez d'utiliser des interfaces si:
Serializable
interface.En termes simples, je voudrais utiliser
interface: pour implémenter un contrat par plusieurs objets indépendants
classe abstraite: pour implémenter un comportement identique ou différent parmi plusieurs objets liés
Jetez un œil à l'exemple de code pour comprendre les choses de manière claire: Comment aurais-je dû expliquer la différence entre une interface et une classe abstraite?
la source
Les enquêteurs aboient un arbre étrange. Pour les langages comme C # et Java, il y a une différence, mais dans d'autres langages comme C ++ il n'y en a pas. La théorie OO ne différencie pas les deux, mais simplement la syntaxe du langage.
Une classe abstraite est une classe à la fois d'implémentation et d'interface (méthodes virtuelles pures) qui sera héritée. Les interfaces n'ont généralement pas d'implémentation mais uniquement des fonctions virtuelles pures.
En C # ou Java, une classe abstraite sans implémentation ne diffère d'une interface que par la syntaxe utilisée pour en hériter et le fait que vous ne pouvez en hériter qu'une.
la source
En implémentant des interfaces, vous obtenez une composition (relations "a-a") au lieu de l'héritage (relations "est-a"). C'est un principe important à retenir quand il s'agit de choses comme les modèles de conception où vous devez utiliser des interfaces pour obtenir une composition de comportements plutôt qu'un héritage.
la source
J'expliquerai les détails de profondeur de l'interface et de la classe abstraite.Si vous connaissez un aperçu de l'interface et de la classe abstraite, la première question vous vient à l'esprit quand nous devons utiliser Interface et quand nous devons utiliser la classe abstraite. Veuillez donc vérifier ci-dessous l'explication de l'interface et de la classe abstraite.
Quand devrions-nous utiliser Interface?
si vous ne connaissez pas la mise en œuvre, nous avons simplement une spécification des exigences, alors nous allons avec Interface
Quand devrions-nous utiliser la classe abstraite?
si vous connaissez l'implémentation mais pas complètement (partiellement l'implémentation), alors nous allons avec la classe Abstract.
Interface
chaque méthode par défaut public abstrait signifie que l'interface est 100% pure abstraite.
Abstrait
peut avoir une méthode concrète et une méthode abstraite, ce qui est une méthode concrète, qui ont une implémentation dans la classe abstraite. Une classe abstraite est une classe qui est déclarée abstraite - elle peut ou non inclure des méthodes abstraites.
Interface
Nous ne pouvons pas déclarer l'interface privée, protégée
Q. Pourquoi ne déclarons-nous pas Interface privée et protégée?
Parce que par défaut, la méthode d'interface est publique abstraite pour telle et telle raison que nous ne déclarons pas l'interface privée et protégée.
Méthode d'interface
ne permet pas non plus de déclarer l'interface comme privée, protégée, finale, statique, synchronisée, native .....
Je donnerai la raison: pourquoi nous ne déclarons pas de méthode synchronisée parce que nous ne pouvons pas créer d'objet d'interface et synchroniser travaillons sur l'objet ainsi et la raison pour laquelle nous ne déclarons pas la méthode synchronisée Le concept transitoire ne s'applique pas non plus parce que le travail transitoire avec synchronisé.
Abstrait
nous sommes heureusement utilisés avec des statiques finales publiques, privées .... signifie qu'aucune restriction n'est applicable dans l'abstrait.
Interface
Les variables sont déclarées dans Interface comme une finale statique publique par défaut, nous ne sommes donc pas non plus déclarées comme une variable privée protégée.
Le modificateur volatil n'est également pas applicable dans l'interface car la variable d'interface est par défaut une variable publique finale et finale statique, vous ne pouvez pas modifier la valeur une fois qu'il a assigné la valeur en variable et une fois que vous avez déclaré la variable en interface, vous devez affecter la variable.
Et la variable volatile continue de changer, donc c'est opp. au final c'est la raison pour laquelle nous n'utilisons pas de variable volatile dans l'interface.
Abstrait
La variable abstraite n'a pas besoin d'être déclarée finale statique publique.
j'espère que cet article est utile.
la source
Abstract class must have at lease one abstract method.
il est possible d'avoir une classe abstraite sans méthode abstraite, tant que vous l'implémentez. RÉFÉRENCE:An abstract class is a class that is declared abstract—it may or may not include abstract methods.
SOURCE DE RÉFÉRENCE: docs.oracle.com/javase/tutorial/java/IandI/abstract.htmlSur le plan conceptuel, conserver l'implémentation, les règles, les avantages spécifiques au langage et atteindre tout objectif de programmation en utilisant n'importe qui ou les deux, peut ou ne peut pas avoir de code / données / propriété, bla bla, héritages simples ou multiples, le tout de côté
1- La classe abstraite (ou pure abstract) est destinée à implémenter la hiérarchie. Si vos objets métier semblent quelque peu similaires sur le plan structurel, représentant uniquement une relation parent-enfant (hiérarchie), les classes héritage / abstrait seront utilisées. Si votre modèle d'entreprise n'a pas de hiérarchie, l'héritage ne doit pas être utilisé (ici, je ne parle pas de logique de programmation, par exemple, certains modèles de conception nécessitent l'héritage). Conceptuellement, la classe abstraite est une méthode pour implémenter la hiérarchie d'un modèle commercial dans la POO, elle n'a rien à voir avec les interfaces, en fait, comparer la classe abstraite avec l'interface n'a pas de sens car les deux sont des choses conceptuellement totalement différentes, il est demandé dans les entretiens juste pour vérifier les concepts car il semble que les deux fournissent quelque peu la même fonctionnalité lorsque l'implémentation est concernée et nous, les programmeurs, insistons généralement davantage sur le codage. [Gardez également à l'esprit que l'abstraction est différente de la classe abstraite].
2- une Interface est un contrat, une fonctionnalité métier complète représentée par un ou plusieurs ensembles de fonctions. C'est pourquoi il est implémenté et non hérité. Un objet métier (faisant partie d'une hiérarchie ou non) peut avoir un nombre illimité de fonctionnalités métier complètes. Cela n'a rien à voir avec les classes abstraites, c'est l'héritage en général. Par exemple, un humain peut RUN, un éléphant peut RUN, un oiseau peut RUN, et ainsi de suite, tous ces objets de hiérarchie différente implémenteraient l'interface RUN ou l'interface EAT ou SPEAK. N'entrez pas dans l'implémentation car vous pourriez l'implémenter comme ayant des classes abstraites pour chaque type implémentant ces interfaces. Un objet de n'importe quelle hiérarchie peut avoir une fonctionnalité (interface) qui n'a rien à voir avec sa hiérarchie.
Je crois que les interfaces n'ont pas été inventées pour réaliser plusieurs héritages ou pour exposer le comportement du public, et de même, les classes abstraites pures ne doivent pas remplacer les interfaces, mais l'interface est une fonctionnalité qu'un objet peut faire (via les fonctions de cette interface) et la classe abstraite représente un parent d'une hiérarchie pour produire des enfants ayant la structure de base (propriété + fonctionnalité) du parent
Lorsque vous êtes interrogé sur la différence, il s'agit en fait d'une différence conceptuelle et non de la différence dans l'implémentation spécifique au langage, sauf demande explicite.
Je pense que les deux enquêteurs s'attendaient à une différence simple entre ces deux éléments et lorsque vous avez échoué, ils ont essayé de vous pousser vers cette différence en implémentant ONE comme OTHER.
la source
Pour .Net,
Votre réponse à La deuxième intervieweuse est aussi la réponse à la première ... Les classes abstraites peuvent avoir une implémentation, ET l'état, les interfaces ne peuvent pas ...
EDIT: Sur une autre note, je n'utiliserais même pas l'expression «sous-classe» (ou l'expression «héritage») pour décrire les classes qui sont «définies pour implémenter» une interface. Pour moi, une interface est une définition d'un contrat auquel une classe doit se conformer si elle a été définie pour «implémenter» cette interface. Il n'hérite de rien ... Vous devez tout ajouter vous-même, explicitement.
la source
Interface : à utiliser si vous souhaitez impliquer une règle sur les composants qui peuvent ou non être liés les uns aux autres
Avantages:
Les inconvénients:
Classe abstraite : doit être utilisée lorsque vous souhaitez avoir un comportement ou une implémentation de base ou par défaut pour les composants liés les uns aux autres
Avantages:
Les inconvénients:
la source
Je pense qu'ils n'ont pas aimé votre réponse parce que vous avez donné les différences techniques au lieu de celles de conception. La question est comme une question de troll pour moi. En fait, les interfaces et les classes abstraites ont une nature complètement différente, vous ne pouvez donc pas vraiment les comparer. Je vais vous donner ma vision de ce qu'est le rôle d'une interface et quel est le rôle d'une classe abstraite.
interface: permet d'assurer un contrat et de réaliser un faible couplage entre les classes afin d'avoir une application plus maintenable, évolutive et testable.
classe abstraite: n'est utilisée que pour factoriser du code entre les classes de la même responsabilité. Notez que c'est la principale raison pour laquelle l'héritage multiple est une mauvaise chose dans la POO, car une classe ne devrait pas gérer de nombreuses responsabilités (utilisez la composition plutôt la ).
Les interfaces ont donc un vrai rôle architectural alors que les classes abstraites ne sont presque qu'un détail d'implémentation (si vous l'utilisez correctement bien sûr).
la source
Les documents indiquent clairement que si une classe abstraite ne contient que des déclarations de méthode abstraite, elle doit plutôt être déclarée comme interface.
Les variables dans les interfaces sont par défaut publiques statiques et finales. La question pourrait être formulée comme si toutes les variables de la classe abstraite étaient publiques? Eh bien, elles peuvent toujours être non statiques et non finales contrairement aux variables dans les interfaces.
Enfin, j'ajouterais un point à ceux mentionnés ci-dessus - les classes abstraites sont toujours des classes et tombent dans un seul arbre d'héritage alors que les interfaces peuvent être présentes dans plusieurs héritages.
la source
C'est mon opinion.
la source
Copié de CLR via C # par Jeffrey Richter ...
J'entends souvent la question: "Dois-je concevoir un type de base ou une interface?" La réponse n'est pas toujours claire.
Voici quelques directives qui pourraient vous aider:
■■ Relation IS-A vs CAN-DO Un type ne peut hériter que d'une implémentation. Si le type dérivé ne peut pas revendiquer une relation IS-A avec le type de base, n'utilisez pas de type de base; utiliser une interface. Les interfaces impliquent une relation CAN-DO. Si la fonctionnalité CAN-DO semble appartenir à différents types d'objets, utilisez une interface. Par exemple, un type peut convertir des instances de lui-même en un autre type (IConvertible), un type peut sérialiser une instance de lui-même (ISerializable), etc. Notez que les types de valeur doivent être dérivés de System.ValueType et, par conséquent, ils ne peuvent pas être dérivés à partir d'une classe de base arbitraire. Dans ce cas, vous devez utiliser une relation CAN-DO et définir une interface.
■■ Facilité d'utilisation En tant que développeur, il est généralement plus facile de définir un nouveau type dérivé d'un type de base que de mettre en œuvre toutes les méthodes d'une interface. Le type de base peut fournir de nombreuses fonctionnalités, de sorte que le type dérivé n'a probablement besoin que de légères modifications de son comportement. Si vous fournissez une interface, le nouveau type doit implémenter tous les membres.
■■ Mise en œuvre cohérente Peu importe la qualité de la documentation d'un contrat d'interface, il est très peu probable que tout le monde le mette en œuvre correctement à 100%. En fait, COM souffre de ce problème, c'est pourquoi certains objets COM fonctionnent correctement uniquement avec Microsoft Word ou avec Windows Internet Explorer. En fournissant un type de base avec une bonne implémentation par défaut, vous commencez par utiliser un type qui fonctionne et est bien testé; vous pouvez ensuite modifier les pièces à modifier.
■■ Versioning Si vous ajoutez une méthode au type de base, le type dérivé hérite de la nouvelle méthode, vous commencez par utiliser un type qui fonctionne et le code source de l'utilisateur n'a même pas besoin d'être recompilé. L'ajout d'un nouveau membre à une interface force l'héritier de l'interface à modifier son code source et à recompiler.
la source
abstract class
.Une interface définit un contrat pour un service ou un ensemble de services. Ils fournissent le polymorphisme de manière horizontale en ce sens que deux classes complètement indépendantes peuvent implémenter la même interface mais être utilisées de manière interchangeable comme paramètre du type d'interface qu'elles implémentent, car les deux classes ont promis de satisfaire l'ensemble des services définis par l'interface. Les interfaces ne fournissent aucun détail d'implémentation.
Une classe abstraite définit une structure de base pour ses sous-classes, et éventuellement une implémentation partielle. Les classes abstraites fournissent le polymorphisme d'une manière verticale, mais directionnelle, en ce sens que toute classe qui hérite de la classe abstraite peut être traitée comme une instance de cette classe abstraite mais pas l'inverse. Les classes abstraites peuvent contenir et contiennent souvent des détails d'implémentation, mais ne peuvent pas être instanciées seules - seules leurs sous-classes peuvent être "renouvelées".
C # permet également l'héritage d'interface, rappelez-vous.
la source
La plupart des réponses se concentrent sur la différence technique entre la classe abstraite et l'interface, mais comme techniquement, une interface est fondamentalement une sorte de classe abstraite (une sans aucune donnée ni implémentation), je pense que la différence conceptuelle est beaucoup plus intéressante, et c'est peut-être ce que les enquêteurs sont après.
Une interface est un accord . Il précise: "c'est ainsi que nous allons nous parler". Il ne peut avoir aucune implémentation car il n'est pas censé avoir d'implémentation. C'est un contrat. C'est comme les
.h
fichiers d'en-tête en C.Une classe abstraite est une implémentation incomplète . Une classe peut ou non implémenter une interface, et une classe abstraite n'a pas à l'implémenter complètement. Une classe abstraite sans implémentation est en quelque sorte inutile, mais totalement légale.
Fondamentalement, toute classe, abstraite ou non, concerne ce qu'elle est , tandis qu'une interface concerne la façon dont vous l'utilisez . Par exemple:
Animal
pourrait être une classe abstraite mettant en œuvre certaines fonctions métaboliques de base, et spécifiant des méthodes abstraites pour la respiration et la locomotion sans donner d'implémentation, car elle n'a aucune idée si elle doit respirer par les branchies ou les poumons, et si elle vole, nage, marche ou rampe.Mount
, d'autre part, pourrait être une interface, qui spécifie que vous pouvez monter l'animal, sans savoir de quel type d'animal il s'agit (ou s'il s'agit d'un animal du tout!).Le fait que dans les coulisses, une interface soit fondamentalement une classe abstraite avec uniquement des méthodes abstraites, n'a pas d'importance. Conceptuellement, ils remplissent des rôles totalement différents.
la source
Comme vous avez peut-être acquis les connaissances théoriques des experts, je ne passe pas beaucoup de mots à répéter tous ceux ici, laissez-moi plutôt expliquer avec un exemple simple où nous pouvons / ne pouvons pas utiliser
Interface
etAbstract class
.Considérez que vous concevez une application pour répertorier toutes les fonctionnalités de Cars. À divers points, vous avez besoin de l'héritage en commun, car certaines propriétés comme DigitalFuelMeter, la climatisation, le réglage du siège, etc. sont communes à toutes les voitures. De même, nous avons besoin de l'héritage pour certaines classes uniquement car certaines propriétés comme le système de freinage (ABS, EBD) ne s'appliquent qu'à certaines voitures.
La classe ci-dessous agit comme une classe de base pour toutes les voitures:
Considérez que nous avons une classe distincte pour chaque voiture.
Considérez que nous avons besoin d'une méthode pour hériter de la technologie de freinage pour les voitures Verna et Cruze (non applicable pour Alto). Bien que les deux utilisent la technologie de freinage, la «technologie» est différente. Nous créons donc une classe abstraite dans laquelle la méthode sera déclarée abstraite et devrait être implémentée dans ses classes enfants.
Maintenant, nous essayons d'hériter de cette classe abstraite et le type de système de freinage est implémenté dans Verna et Cruze:
Vous voyez le problème dans les deux classes ci-dessus? Ils héritent de plusieurs classes que C # .Net n'autorise pas même si la méthode est implémentée dans les enfants. Ici vient le besoin d'Interface.
Et l'implémentation est donnée ci-dessous:
Verna et Cruze peuvent désormais obtenir plusieurs héritages avec leur propre type de technologies de freinage à l'aide d'Interface.
la source
Les interfaces sont un moyen léger d'imposer un comportement particulier. C'est une façon de penser.
la source
Ces réponses sont trop longues.
Les interfaces servent à définir des comportements.
Les classes abstraites servent à définir une chose elle-même, y compris ses comportements. C'est pourquoi nous créons parfois une classe abstraite avec des propriétés supplémentaires héritant d'une interface.
Cela explique également pourquoi Java ne prend en charge que l'héritage unique pour les classes mais n'impose aucune restriction sur les interfaces. Parce qu'un objet concret ne peut pas être différent, mais il peut avoir des comportements différents.
la source
1) Une interface peut être considérée comme une pure classe abstraite, est la même, mais malgré cela, n'est pas la même pour implémenter une interface et hériter d'une classe abstraite. Lorsque vous héritez de cette pure classe abstraite, vous définissez une hiérarchie -> héritage, si vous implémentez l'interface que vous n'êtes pas, et vous pouvez implémenter autant d'interfaces que vous le souhaitez, mais vous ne pouvez hériter que d'une seule classe.
2) Vous pouvez définir une propriété dans une interface, donc la classe qui implémente cette interface doit avoir cette propriété.
Par exemple:
La classe qui implémente cette interface doit avoir une propriété comme celle-ci.
la source
Bien que cette question soit assez ancienne, je voudrais ajouter un autre point en faveur des interfaces:
Les interfaces peuvent être injectées à l'aide de n'importe quel outil d'injection de dépendances alors que l'injection de classe abstraite est prise en charge par très peu.
la source
D' une autre réponse de moi , traitant principalement quand utiliser l'un contre l'autre:
la source
Types d'interface et classes de base abstraites
Adapté du livre Pro C # 5.0 et du livre .NET 4.5 Framework .
Le type d'interface peut sembler très similaire à une classe de base abstraite. Rappelons que lorsqu'une classe est marquée comme abstraite, elle peut définir n'importe quel nombre de membres abstraits pour fournir une interface polymorphe à tous les types dérivés. Cependant, même lorsqu'une classe définit un ensemble de membres abstraits, elle est également libre de définir n'importe quel nombre de constructeurs, de données de champ, de membres non abstraits (avec implémentation), etc. Les interfaces, en revanche, ne contiennent que des définitions de membres abstraites. L'interface polymorphe établie par une classe parent abstraite souffre d'une limitation majeure en ce que seuls les types dérivés prennent en charge les membres définis par le parent abstrait. Cependant, dans les grands systèmes logiciels, il est très courant de développer plusieurs hiérarchies de classes qui n'ont pas de parent commun au-delà de System.Object. Étant donné que les membres abstraits d'une classe de base abstraite ne s'appliquent qu'aux types dérivés, nous n'avons aucun moyen de configurer les types dans différentes hiérarchies pour prendre en charge la même interface polymorphe. À titre d'exemple, supposons que vous avez défini la classe abstraite suivante:
Compte tenu de cette définition, seuls les membres qui étendent CloneableType peuvent prendre en charge la méthode Clone (). Si vous créez un nouvel ensemble de classes qui n'étendent pas cette classe de base, vous ne pouvez pas obtenir cette interface polymorphe. En outre, vous vous souvenez peut-être que C # ne prend pas en charge l'héritage multiple pour les classes. Par conséquent, si vous souhaitez créer un Mini Van qui est une voiture et un type clonable, vous ne pouvez pas le faire:
Comme vous pouvez le deviner, les types d'interface viennent à la rescousse. Une fois qu'une interface a été définie, elle peut être implémentée par n'importe quelle classe ou structure, dans n'importe quelle hiérarchie, dans n'importe quel espace de noms ou n'importe quel assembly (écrit dans n'importe quel langage de programmation .NET). Comme vous pouvez le voir, les interfaces sont hautement polymorphes. Considérez l'interface .NET standard nommée ICloneable, définie dans l'espace de noms System. Cette interface définit une seule méthode nommée Clone ():
la source
Réponse à la deuxième question: la
public
variable définie dansinterface
eststatic final
par défaut tandis que lapublic
variable dans laabstract
classe est une variable d'instance.la source
Bien sûr, il est important de comprendre le comportement de l'interface et de la classe abstraite dans la POO (et comment les langages les gèrent), mais je pense qu'il est également important de comprendre ce que signifie exactement chaque terme. Pouvez-vous imaginer que la
if
commande ne fonctionne pas exactement comme le sens du terme? De plus, en fait, certaines langues réduisent, encore plus, les différences entre une interface et un résumé ... si par hasard un jour les deux termes fonctionnent presque de manière identique, au moins vous pouvez vous définir où (et pourquoi) l'un d'eux devrait être utilisé pour.Si vous lisez certains dictionnaires et d'autres polices, vous pouvez trouver différentes significations pour le même terme, mais ayant des définitions communes. Je pense que ces deux significations que j'ai trouvées sur ce site sont vraiment, vraiment bonnes et appropriées.
Interface:
Abstrait:
Exemple:
Vous avez acheté une voiture et elle a besoin de carburant.
Votre modèle de voiture est
XYZ
, qui est du genreABC
, c'est donc une voiture en béton, un exemple spécifique d'une voiture. Une voiture n'est pas un véritable objet. En fait, c'est un ensemble abstrait de normes (qualités) pour créer un objet spécifique. Bref, Car est une classe abstraite , c'est "quelque chose qui concentre en soi les qualités essentielles de tout ce qui est plus étendu ou plus général" .Le seul carburant correspondant aux spécifications du manuel du véhicule doit être utilisé pour remplir le réservoir du véhicule. En réalité, rien ne vous empêche de mettre du carburant, mais le moteur ne fonctionnera correctement qu'avec le carburant spécifié, il est donc préférable de suivre ses exigences. Les exigences disent qu'il accepte, comme d'autres voitures du même genre
ABC
, un ensemble standard de carburant.Dans une vue orientée objet, le carburant pour le genre
ABC
ne doit pas être déclaré en tant que classe car il n'y a pas de carburant concret pour un genre spécifique de voiture. Bien que votre voiture puisse accepter une classe abstraite de carburant ou de carburant pour véhicules, vous devez vous rappeler que seuls certains des carburants pour véhicules existants répondent aux spécifications, celles qui mettent en œuvre les exigences du manuel de votre voiture. En bref, ils devraient implémenter l' interfaceABCGenreFuel
qui "... permet à des éléments séparés et parfois incompatibles de se coordonner efficacement" .Addenda
De plus, je pense que vous devez garder à l'esprit la signification du terme classe, qui est (du même site mentionné précédemment):
Classe:
De cette façon, une classe (ou classe abstraite) ne devrait pas représenter uniquement des attributs communs (comme une interface), mais une sorte de groupe avec des attributs communs. Une interface n'a pas besoin de représenter une sorte. Il doit représenter des attributs communs. De cette façon, je pense que les classes et les classes abstraites peuvent être utilisées pour représenter des choses qui ne devraient pas changer souvent ses aspects, comme un être humain un mammifère, car elles représentent certaines sortes. Les types ne devraient pas se changer si souvent.
la source
Du point de vue du codage
Une interface peut remplacer une classe abstraite si la classe abstraite n'a que des méthodes abstraites. Sinon, changer la classe Abstract en interface signifie que vous perdrez la réutilisation du code qu'offre l'héritage.
Du point de vue du design
Conservez-le en tant que classe abstraite s'il s'agit d'une relation "Est une" et que vous avez besoin d'un sous-ensemble ou de toutes les fonctionnalités. Conservez-le en tant qu'interface s'il s'agit d'une relation «devrait faire».
Décidez de ce dont vous avez besoin: juste l'application de la politique ou la réutilisation du code ET la politique.
la source
Quelques autres différences:
Les classes abstraites peuvent avoir des méthodes statiques, des propriétés, des champs, etc. et les opérateurs, pas les interfaces. L'opérateur de transtypage permet de transtyper vers / depuis la classe abstraite, mais ne permet pas de transtyper vers / depuis l'interface.
Donc, à peu près, vous pouvez utiliser la classe abstraite seule, même si elle n'est jamais implémentée (via ses membres statiques) et vous ne pouvez pas utiliser l'interface seule de quelque manière que ce soit.
la source