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


J'ai récemment eu deux entrevues téléphoniques au cours desquelles on m'a demandé quelles étaient les différences entre une classe Interface et une classe abstraite. J'ai expliqué tous les aspects auxquels je pouvais penser, mais il semble qu'ils attendent que je mentionne quelque chose de précis, et je ne sais pas ce que c'est.

D'après mon expérience, je pense que ce qui suit est vrai. Si un point important me manque, veuillez me le faire 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 classe abstraite uniquement en raison de l'inexistence de Multi-héritage en C #.

  1. Après tout cela, l'intervieweur a soulevé la question «Et si vous aviez un cours abstrait avec seulement 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 vous aviez une variable Public à l'intérieur de l'interface, en quoi cela serait-il différent 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 également:


1197
2018-04-17 16:42


origine


Réponses:


Alors que votre question indique que c'est pour "OO général", il semble vraiment se concentrer sur l'utilisation .NET de ces termes.

En .NET (similaire pour Java):

  • les interfaces peuvent ne pas avoir d'état ou de mise en œuvre
  • 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 l'état (membres de données) et / ou l'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 à plusieurs, les classes abstraites ne le peuvent pas (c'est probablement la raison concrète pour laquelle les interfaces existent séparément des classes abtract) elles permettent une implémentation de l'héritage multiple qui élimine beaucoup des problèmes de MI général.

En tant que termes OO généraux, les différences ne sont pas nécessairement bien définies. Par exemple, il existe 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 d'autres peuvent dire qu'une classe abstraite avec des implémentations par défaut est encore une interface ou une La classe peut encore définir une interface.

En effet, il existe un idiome C ++ appelé l'interface non-virtuelle (NVI) où les méthodes publiques sont des méthodes non-virtuelles qui «thunk» aux méthodes virtuelles privées:


632
2018-04-17 17:18



Que diriez-vous d'une analogie: lorsque j'étais dans l'armée de l'air, je suis allé à l'entraînement de pilote et suis devenu un pilote de l'USAF (US Air Force). À ce moment-là, je n'étais pas qualifié pour voler quoi que ce soit et je devais suivre une formation de type avion. Une fois qualifié, j'étais pilote (classe abstraite) et pilote C-141 (cours concret). Lors d'une de mes missions, on m'a confié un devoir supplémentaire: officier de sécurité. Maintenant, j'étais encore pilote et pilote de C-141, mais j'ai également effectué des tâches 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 auraient pu le faire aussi.

Tous les pilotes de l'USAF doivent suivre certaines règles de l'Air Force, et tous les pilotes C-141 (ou F-16, ou T-38) sont des pilotes de l'USAF. N'importe qui peut être un agent de sécurité. Donc, pour résumer:

  • Pilote: classe abstraite
  • C-141 Pilot: classe concrète
  • ISafety Officer: interface

note ajoutée: ceci était censé ê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.


754
2017-08-30 04:40



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 de base et le comportement de la classe abstraite. Le type de comportement qui définit réellement la classe.

D'autre part, l'héritage de l'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 de comportement d'une classe abstraite automobile, mais ils partagent aussi un comportement périphérique comme Générer des gaz d'échappement que même des classes non automobiles comme Drillers ou PowerGenerators partagent et ne définit pas nécessairement une voiture ou un camion , Car, Truck, Driller et PowerGenerator peuvent tous partager la même interface IExhaust.


194
2017-08-31 12:09



Short: Les classes abstraites sont utilisées pour La modélisation une hiérarchie de classe de classes similaires (par exemple Animal peut être une classe abstraite et Human, Lion, Tiger peuvent être des classes dérivées concrètes)

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 Humain, Bâtiment, Arbre.) Peu importe si vous pouvez manger, vous pouvez nager peut mourir ou n'importe quoi .. il importe seulement une chose que vous devez avoir Hauteur (mise en œuvre dans votre classe)).


163
2018-04-05 09:53



Il y a quelques autres différences -

Les interfaces ne peuvent avoir aucune implémentation concrète. Les classes de base abstraites peuvent. Cela vous permet de fournir des implémentations concrètes là-bas. Cela peut permettre à une classe de base abstraite de fournir un contrat plus rigoureux, alors qu'une interface ne décrit réellement que l'utilisation d'une classe. (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.)

Plus d'une interface peut être implémentée 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 en utilisant des interfaces.

Les classes de base abstraites peuvent être modifiées dans v2 + sans casser l'API. Les modifications apportées aux interfaces perturbent les changements.

[C # /. NET Specific] Les interfaces, contrairement aux 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 comportementaux / des directives d'utilisation sur les types de valeur.


74
2018-04-17 16:46



Héritage
Considérons une voiture et un bus. Ce sont deux véhicules différents. Mais encore, ils partagent quelques 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 à propos de 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 incomplet objets. Pour mieux comprendre, considérons l'analogie du véhicule une fois de plus.
Un véhicule peut être conduit. Droite? Mais différents véhicules sont conduits de différentes façons ... 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 quel type de véhicule il est et de le piloter avec sa propre fonction; vous devriez changer la classe de conducteur encore et encore en ajoutant un nouveau type de véhicule.
Voici le rôle des classes et des méthodes abstraites. Vous pouvez définir la méthode de lecteur comme abstraite pour indiquer que tous les enfants héritiers doivent implémenter cette fonction.
Donc, si vous modifiez la classe de 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 sera pas compilé 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 pas de propriétés. Ils indiquent simplement que les enfants héritiers sont capables de faire quelque chose ...
Supposons que vous avez différents types de téléphones mobiles avec vous. Chacun d'eux a différentes façons de faire différentes fonctions; Ex: appeler une personne. Le fabricant du téléphone spécifie comment le faire. Ici, les téléphones mobiles peuvent composer un numéro - c'est-à-dire, il est dial-able. Représenter ceci comme une interface.

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

Ici, le fabricant du Dialable définit comment composer un numéro. Vous avez juste besoin 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 ici des interfaces au lieu de classes abstraites, l'auteur de la fonction qui utilise un Dialable n'a pas besoin de s'inquiéter de ses propriétés. Ex: A-t-il un écran tactile ou un clavier, Est-ce un téléphone fixe fixe ou un téléphone mobile. Vous avez juste besoin de savoir s'il est possible de le numéroter. hérite-t-il (ou implémente-t-il) l'interface Dialable?

Et plus important, 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 composant ne dépend pas (et ne peut pas) des détails autres que ceux spécifiés dans l'interface Dialable. Ils implémentent tous deux une interface Dialable et c'est la seule chose sur laquelle la fonction se soucie.

Les interfaces sont couramment utilisées par les développeurs pour assurer l'interopérabilité (utilisation interchangeable) entre 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 avez juste besoin de 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 parente.

Plus d'informations Classes abstraites vs interfaces 


63
2018-06-14 13:11



Si vous considérez java En tant que langage POO pour répondre à cette question, la version Java 8 rend obsolète une partie du contenu des réponses ci-dessus. Maintenant, l'interface java peut avoir des méthodes par défaut avec une implémentation concrète.

Oracle site Internet fournit des différences clés entre interface et abstract classe.

Envisagez d'utiliser des classes abstrait 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 protected et private).
  3. Vous voulez déclarer des champs non statiques ou non finaux.

Envisagez d'utiliser des si :

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

En termes simples, je voudrais utiliser

interface: Pour implémenter un contrat avec plusieurs objets indépendants

classe abstraite: Pour implémenter le même comportement ou un comportement différent parmi plusieurs objets associés

Jetez un oeil à l'exemple de code pour comprendre les choses de manière claire: Comment aurais-je expliqué la différence entre une interface et une classe abstraite?


33
2017-11-27 19:20



Les intervieweurs 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 avec l'implémentation et l'interface (méthodes virtuelles pures) qui seront héritées. 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 aucune implémentation diffère d'une interface uniquement dans la syntaxe utilisée pour en hériter et le fait que vous ne pouvez hériter que d'une seule.


30
2018-04-17 16:48