Interface vs classe abstraite (OO général)

1413

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 #.

  1. 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?

  2. 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 :

Houman
la source
412
Bien que je pense qu'il est important de connaître la différence entre les deux, ce n'est pas une bonne question d'entrevue, imo. Sauf si le travail consistait à écrire un livre sur des sujets OO. Il vaut mieux ne pas travailler pour ces chauves-souris.
Alan
107
@Alan: En fait, j'aime ça comme une question d'entrevue, mais je ne pourrais pas traquer quelqu'un de cette façon - je le posterais probablement plus comme "Où choisiriez-vous une interface plutôt qu'une classe de base abstraite, lors de la définition d'une hiérarchie? ", ou quelque chose de similaire.
Reed Copsey
11
Peut-être qu'ils recherchaient une réponse plus axée sur le design ... même si comme vous, je l'aurais traitée comme une question technique.
CurtainDog
16
Belles
Rajat_R
30
@Kave: 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.
un apprenant du

Réponses:

746

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):

  • les interfaces ne peuvent avoir ni état ni implémentation
  • une classe qui implémente une interface doit fournir une implémentation de toutes les méthodes de cette interface
  • les classes abstraites peuvent contenir un état (membres de données) et / ou une implémentation (méthodes)
  • les classes abstraites peuvent être héritées sans implémenter les méthodes abstraites (bien qu'une telle classe dérivée soit elle-même abstraite)
  • les interfaces peuvent être héritées de plusieurs façons, les classes abstraites peuvent ne pas l'être (c'est probablement la raison concrète clé pour que les interfaces existent séparément des classes abtract - elles permettent une implémentation de l'héritage multiple qui supprime de nombreux problèmes de MI général).

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:

Michael Burr
la source
7
Je vous remercie. Je pense que puisque votre réponse mentionne l'état + un bon aperçu de tout le reste, je marque votre réponse comme une réponse finale. Vous avez raison, j'ai demandé un OO général, puisque mon premier intervieweur a demandé un OO général, mais comme je suis un gars C #, j'ai tendance à l'oublier. ;-) Merci aussi pour l'explication C ++, comme toujours c ++ est époustouflant.
Houman
6
Je pense qu'un point clé dans l'explication fournie par Michael est que lors de la mise en œuvre d'une interface, vous DEVEZ implémenter tous les membres de l'interface, mais lorsque vous héritez d'une classe abstraite, il n'est PAS OBLIGATOIRE par une classe enfant d'implémenter les membres de ses parents
Guillermo Gomez
82
+1: Je serais prêt à parier que les singes qui hébergent l'interview ne réalisent même pas que d'autres langues implémentent OO différemment.
Courses de légèreté en orbite le
2
@JL Je ne vois pas où est le problème. Vous semblez avoir confondu méthode abstraite et classe abstraite. Les méthodes abstraites n'ont aucune implémentation. Cependant, à l'intérieur d'une classe abstraite , certaines méthodes peuvent être abstraites (c'est-à-dire sans implémentation) tandis que d'autres peuvent en effet avoir une implémentation.
xji
19
Notez que dans Java 8, vous pouvez désormais avoir des méthodes par défaut et des méthodes statiques dans les interfaces, ce qui signifie que les interfaces Java peuvent avoir une implémentation. Référence ici . De toute évidence, vous avez fait référence principalement à .NET, il ne s'agit donc que d'une observation faisant référence à Java.
davtom
867

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:

  • Pilote: classe abstraite
  • C-141 Pilot: classe béton
  • Agent de sécurité: interface

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.

Geai
la source
87
J'aime vraiment cette analogie, elle utilise un exemple simple pour expliquer un sujet légèrement complexe
Kevin Bowersox
13
C'est la meilleure façon de comprendre la terminologie OO complexe. Bref, toute théorie ne vaut que si vous pouvez vous en servir pratiquement. @Jay you rexample est vraiment facile à saisir, puis plusieurs points de balle (principalement l'esprit pénétrant au lieu d'être absorbé!)
vs
54
Je suis encore un peu confus. Disons que vous avez maintenant les qualifications F-16 et T-38, donc maintenant la classe Jayne 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? Merci
Alex Okrushko
37
Beaucoup de gens ont donné à juste titre un +1 au commentaire d'Alex, car cela révèle une certaine faiblesse dans cet exemple. Tout d'abord, je dirais que Jay serait une instance de C-141Pilot plutôt que sa propre classe. De plus, comme à l'USAF, 99% de tous les pilotes ne sont qualifiés que dans un seul avion à la fois (FCF et pilotes d'essai étant des exceptions notables), je n'ai pas considéré les qualifications multiples et comment cela pourrait être mis en œuvre. Comme je connais un pilote qui, il y a 50 ans, était qualifié dans 25 avions différents simultanément, je pense que cela illustre comment nous ne voulons PAS utiliser l'héritage multiple.
Jay
20
Puisqu'il est peu probable qu'un pilote pilote plus d'un avion à la fois, ce serait une bonne occasion de mettre en œuvre le modèle de stratégie. Un pilote aurait une collection de certifications et sélectionnerait la bonne au moment de l'exécution. Les certifications seraient codées comme des comportements qui implémenteraient l'interface IFlyPlane, avec les méthodes TakeOff, Land, Eject.
Michael Blackburn
221

Je 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.

Prasun
la source
32
Je pense qu'une analogie encore meilleure serait "usesFuel" qui montrerait la nature contractuelle de l'interface.
Pureferret
@Pureferret si acceleratefait partie du comportement de base de la classe abstraite Automobile, alors je ne peux pas dire que cela acceleratemontre la nature du contrat . qu'est-ce que la nature du contrat? pourquoi ce mot est contractintroduit chaque fois que nous parlons interface?
suréchange
@overexchange parce que généralement l'interface est juste là où deux «surfaces» se rencontrent, mais le mot contrat implique qu'il existe un accord sur la façon dont les deux «surfaces» se rencontrent. Cela n'a pas de sens (du moins pour moi) que de générer un échappement soit quelque chose sur lequel vous êtes "d'accord". Mais il est logique (encore une fois pour moi) que vous puissiez vous mettre d'accord sur la nécessité d'utiliser Fuel.
Pureferret
1
@Pureferret j'ai posé une question sur le lien pour la même chose
overexchange
1
@Pureferret si interfacedoit avoir un comportement périphérique, alors pourquoi public interface List<E> extends Collection<E> {}est conçu pour décrire le comportement de base de list? cela contredit en fait la réponse de Prasun. Les deux Collection<E>et List<E>sont des interfaces ici.
suréchange
198

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)).

Dhananjay
la source
7
J'aime vraiment cette réponse car il est parfois difficile de répondre au «quoi» qui est différent entre les choses en regardant quelque chose de plus abstrait comme l' intention , au lieu de la seule structure (car structurellement, une interface et une pure classe abstraite sont à peu près les mêmes chose).
LostSalad
Il est facile d'énumérer ce qu'une classe abstraite par rapport à une interface peut faire dans un langage spécifique, mais il est plus difficile de créer une abstraction pour donner un sens et une responsabilité à l'objet et ce que vous avez dit reprend totalement l'utilisation du concept 2 dans OO. Merci!
Samuel
2
@dhananjay: je vois comment la hauteur peut être séparée du concept de la classe animale et peut être d'une autre classe différente, mais qu'entendez-vous exactement par "communication" entre les classes? Il s'agit simplement de définir Hauteur pour sa propre classe, n'est-ce pas?
TTT
77

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.

Reed Copsey
la source
6
+1 pour le point clé selon lequel plusieurs interfaces peuvent être implémentées sur une classe.
cgp
C'est le véritable avantage des interfaces sur les classes de base abstraites, IMO. Sinon, je suis d'accord avec les directives de conception .NET, qui disent désormais "préférer les classes de base abstraites aux interfaces"
Reed Copsey
Cependant, ce serait intéressant si vous pouviez ajouter le fait que c'est aussi des interfaces qui peuvent être appliquées à n'importe quelle classe.
cgp
1
@altCognito: J'ai pensé que c'était un peu géré avec le deuxième paragraphe. Cela m'a cependant rappelé que les interfaces fonctionnent sur les types de valeur, j'ai donc ajouté cela.
Reed Copsey
Merci beaucoup pour cette description exacte. C'est en effet très utile. Je suis nouveau ici. Il est dommage que vous ne puissiez pas sélectionner deux réponses comme "réponse". Une chose qui m'embrouille est votre utilisation de la classe abstraite «de base». Toutes les classes abstraites sont censées être une classe de base d'une sous-classe. Pourquoi nommer la «base» supplémentaire?
Houman
68

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 ...

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Maintenant un vélo ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

Et une voiture ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

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 ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

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.

public interface Dialable {
    public void dial(Number n);
}

Ici, le fabricant du Dialable définit comment composer un numéro. Il vous suffit de lui donner un numéro à composer.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

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

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

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

fz_salam
la source
Il n'est pas vrai que "les interfaces n'ont pas de propriétés".
Bigeyes
@Bigeyes, java n'autorise pas les propriétés dans les interfaces. Je pensais que c'était la même chose dans d'autres langues. Pourriez-vous s'il vous plaît expliquer plus?
fz_salam
Je fais référence à C # /. Net. Veuillez voir l' exemple
Bigeyes
@Bigeyes for C # où les interfaces peuvent avoir des propriétés, cela ne réintroduit-il pas le problème de l'héritage multiple? Que se passe-t-il lorsqu'une classe utilise plusieurs interfaces qui ont défini la même propriété? Juste curieux merci
stackPusher
@happycoder: re: "Ici, en utilisant des interfaces au lieu de classes abstraites, vous n'avez pas à vous soucier de ses propriétés. Ex: a-t-il un écran tactile ou un clavier téléphonique, 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 dialable; hérite-t-il (ou implémente-t-il) l'interface Dialable. " - pouvez-vous montrer cela dans un exemple de code, n'a pas non plus vu comment il serait hérité ...
TTT
45

Si vous considérez javacomme 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 interfaceet la abstractclasse.

Envisagez d'utiliser des classes abstraites si:

  1. Vous souhaitez partager du code entre plusieurs classes étroitement liées.
  2. Vous vous attendez à ce que les classes qui étendent votre classe abstraite aient de nombreuses méthodes ou champs communs, ou nécessitent des modificateurs d'accès autres que publics (tels que protégés et privés).
  3. Vous souhaitez déclarer des champs non statiques ou non définitifs.

Envisagez d'utiliser des interfaces si:

  1. Vous vous attendez à ce que des classes indépendantes implémentent votre interface. Par exemple, de nombreux objets indépendants peuvent implémenterSerializable interface.
  2. Vous souhaitez spécifier le comportement d'un type de données particulier, mais ne vous souciez pas de savoir qui implémente son comportement.
  3. Vous souhaitez profiter de l'héritage multiple de type.

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?

Ravindra babu
la source
33

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.

Steve Rowe
la source
On m'a posé la même question il y a une semaine, je n'ai aucune expérience avec Java mais je travaille avec C ++ depuis un moment maintenant. L'intervieweur n'a pas spécifié de langues avant de poser la question, j'ai donc expliqué que les interfaces dans ce cas étaient des classes abstraites sans état ni implémentation d'aucune sorte. Je conviens que c'est aussi une question étrange.
dacabdi
31

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.

TheTXI
la source
17
Les interfaces atteignent, à l'OMI, davantage une relation "Agit comme un". L'encapsulation permet une meilleure composition qu'une interface.
Reed Copsey
12
Je ne pense pas que la mise en œuvre des interfaces relève de la composition.
Pavan Dittakavi
De plus, l'interface est plus susceptible d'être utilisée pour décrire la «capacité», comme IDisposable. Il avait l'habitude de partager la fonctionnalité entre les classes pour que ces classes "puissent faire" quelque chose. Plus d'exemples IFlyable peut être implémenté par oiseau et par avion. Mais Bird peut dériver de Class Creature où les avions dérivent d'AirCraft.
Peter.Wang
26

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.

  1. 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

  2. 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.

JegsVala
la source
4
Je ne suis pas d'accord avec ce point: 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.html
Devner
Vous parlez de détails techniques et d'implémentation, vous ne répondez pas à la question en termes de POO général
Billal Begueradj
26

Sur 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.

Et si vous aviez une classe abstraite avec uniquement des méthodes abstraites?

bjan
la source
Cela résume assez bien la réponse à cette question.
pranavn
fonctionnalité implémentée vs structure étendue, sympa!
harshvchawla
21

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.

Charles Bretana
la source
2
Oui! Etat! C'est ce que le deuxième intervieweur voulait dire avec sa façon étrange de dire «variable publique» à l'intérieur d'une interface. ça alors! Les classes abstraites peuvent avoir un état, les interfaces non! Et oui, tout le monde est également d'accord sur les différences entre leurs modes de succession, que j'avais oublié de mentionner mais que j'ai compris plus tard. :) Merci tout le monde!
Houman
4
Plus qu'un simple état .... Les classes abstraites peuvent avoir une MISE EN ŒUVRE. c'est-à-dire qu'ils peuvent avoir des méthodes avec du code qui s'exécutent et font quelque chose, qui sont héritées et exécutées par les instances des classes de base ... Pas avec les interfaces
Charles Bretana
Encore plus que cela, dans un sens, les classes abstraites PEUVENT être instanciées, elles n'ont qu'à être instanciées en utilisant une définition de classe dérivée, pas directement. Mais les variables d'état définies dans la classe abstraite sont instanciées dans l'objet créé en renouvelant une instance de la classe dérivée. Cette instance EST une instance de la classe abstraite en plus d'être une instance de la classe dérivée - elle en est après tout dérivée. Rien de tout cela n'est vrai pour une interface.
Charles Bretana
Lorsque vous créez une instance d'une classe définie pour implémenter une interface, ce n'est pas une "instance" de cette interface, toute la syntaxe fait que le compilateur examine le code de la classe et s'assure que chaque comportement (méthode, propriété , event, eventHandler, etc.) qui est défini par l'interface a été implémenté dans le code de la classe.
Charles Bretana
20

Interface : à utiliser si vous souhaitez impliquer une règle sur les composants qui peuvent ou non être liés les uns aux autres

Avantages:

  1. Permet l'héritage multiple
  2. Fournit une abstraction en n'exposant pas le type exact d'objet utilisé dans le contexte
  3. assure la cohérence par une signature spécifique du contrat

Les inconvénients:

  1. Doit mettre en œuvre tous les contrats définis
  2. Ne peut pas avoir de variables ou de délégués
  3. Une fois défini, il ne peut pas être modifié sans casser toutes les classes

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:

  1. Plus rapide que l'interface
  2. A une flexibilité dans la mise en œuvre (vous pouvez la mettre en œuvre entièrement ou partiellement)
  3. Peut être facilement modifié sans casser les classes dérivées

Les inconvénients:

  1. Ne peut pas être instancié
  2. Ne prend pas en charge l'héritage multiple
webmaster bourax
la source
Définissez plus rapidement. Est-ce significatif? Qu'est-ce que cela signifie même? l'opcode pour l'appel de fonction sur une classe abstraite est plus rapide que l'opcode pour l'invocation de fonction sur une interface?
denis631
Les classes abstraites @ denis631 sont légèrement plus rapides que l'interface car la recherche et l'appel sont impliqués dans la méthode d'interface. lire ce coderanch.com/t/503450/java/abstract-class-faster-interface
webmaster bourax
17

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).

Gnucki
la source
13
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

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.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

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.

Aniket Thakur
la source
13
  1. Interface:
    • Nous n'implémentons pas (ou ne définissons pas) de méthodes, nous le faisons dans des classes dérivées.
    • Nous ne déclarons pas de variables membres dans les interfaces.
    • Les interfaces expriment la relation HAS-A. Cela signifie qu'ils sont un masque d'objets.
  2. Classe abstraite:
    • Nous pouvons déclarer et définir des méthodes en classe abstraite.
    • Nous en cachons les constructeurs. Cela signifie qu'aucun objet n'est créé directement à partir de celui-ci.
    • La classe abstraite peut contenir des variables membres.
    • Les classes dérivées héritent de la classe abstraite, ce qui signifie que les objets des classes dérivées ne sont pas masqués, ils héritent de la classe abstraite. Dans ce cas, la relation est IS-A.

C'est mon opinion.

nautilusvn
la source
12

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.

Deepak Mishra
la source
1
@AbdullahShoaib est un et n'importe qui peut le faire mais pas le faire, il y a une différence ici. c'est la raison fondamentale, nous avons besoin d'une interface. comportement can-do fera également partie de abstract class.
suréchange
10

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.

joelmdev
la source
1
En utilisant les termes horizontal et vertical, il était très clair d'imaginer la différence.
Infinity
10

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 .hfichiers 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: Animalpourrait ê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.

mcv
la source
10

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 Interfaceet Abstract 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:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Considérez que nous avons une classe distincte pour chaque voiture.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

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.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

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:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

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.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

Et l'implémentation est donnée ci-dessous:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Verna et Cruze peuvent désormais obtenir plusieurs héritages avec leur propre type de technologies de freinage à l'aide d'Interface.

Sarath Avanavu
la source
4
C'est l'une des meilleures explications à cause des exemples.
Adam Mendoza
2
Cela me semble logique sans ébranler le cerveau. J'essayais juste de trouver un exemple de voiture pour mes élèves. Merci d'avoir pris le temps de mettre cela ensemble.
tazboy
9

Les interfaces sont un moyen léger d'imposer un comportement particulier. C'est une façon de penser.

fastcodejava
la source
8

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.

K.Miao
la source
7

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:

  public interface IVariable
  {
      string name {get; set;}
  }

La classe qui implémente cette interface doit avoir une propriété comme celle-ci.

MRFerocius
la source
7

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.

py2020
la source
1
Je pense que vous voulez dire qu'un outil DI peut injecter une classe qui implémente une interface. Certains de ces outils peuvent également injecter des classes dérivées d'une classe abstraite, ou dites-vous que c'est impossible?
John Saunders
6

D' une autre réponse de moi , traitant principalement quand utiliser l'un contre l'autre:

D'après mon expérience, les interfaces sont mieux utilisées lorsque vous avez plusieurs classes qui doivent chacune répondre à la même méthode ou aux mêmes méthodes afin qu'elles puissent être utilisées de manière interchangeable par un autre code qui sera écrit contre l'interface commune de ces classes. La meilleure utilisation d'une interface est lorsque le protocole est important mais que la logique sous-jacente peut être différente pour chaque classe. Si vous dupliquez autrement la logique, pensez plutôt aux classes abstraites ou à l'héritage de classe standard.

Adam Alexander
la source
6

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:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

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:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

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 ():

public interface ICloneable
{
object Clone();
}
Dit Roohullah Allem
la source
6

Réponse à la deuxième question: la publicvariable définie dans interfaceest static finalpar défaut tandis que la publicvariable dans la abstractclasse est une variable d'instance.

Ravindra babu
la source
6

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 ifcommande 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:

Une chose ou une circonstance qui permet à des éléments séparés et parfois incompatibles de se coordonner efficacement.

Abstrait:

Quelque chose qui concentre en soi les qualités essentielles de quelque chose de plus étendu ou de plus général, ou de plusieurs choses; essence.

Exemple:

Vous avez acheté une voiture et elle a besoin de carburant.

entrez la description de l'image ici

Votre modèle de voiture est XYZ, qui est du genre ABC, 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 genreABC , un ensemble standard de carburant.

Dans une vue orientée objet, le carburant pour le genre ABCne 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' interface ABCGenreFuel 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:

Un certain nombre de personnes ou de choses considérées comme formant un groupe en raison d'attributs, de caractéristiques, de qualités ou de traits communs; gentil;

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.

Felypp Oliveira
la source
1
trop de peluches, ne faites pas sembler plus déroutant pour les gens qu'il ne l'est déjà.
ganjeii
5

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.

Vivek Vermani
la source
3

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.

Orlin Petrov
la source
en Java, l'interface peut avoir une variable membre mais par défaut, ils deviennent publics statiques .. donc l'interface peut avoir des champs statiques
Jitendra Vispute
Oui, l'interface peut avoir des champs statiques. MAIS l'interface ne peut pas avoir de méthodes statiques.
un apprenant