Quelle est la différence entre une interface et une classe abstraite?


1753

Quelle est exactement la différence entre une interface et une classe abstraite?


96
Il s'agit d'une question d'entrevue extrêmement courante. C'est surprenant car une classe abstraite est rarement utilisée dans les solutions par rapport à d'autres choses. Votre question m'a aidé Safraz.
Catto

5
Cette question pourrait également aider à comprendre le concept d'interfaces stackoverflow.com/q/8531292/1055241
gprathour

6
J'ai supprimé la balise PHP de cette question, car presque aucune des réponses n'est spécifique à la langue et la question elle-même n'est pas spécifique à la langue.
brice

2
retour dans la journée en c ++ une interface est une pure classe de base abstraite avec toutes les implémentations de méthode = 0. Si une seule méthode n'était pas = 0, alors elle a une implémentation et la base abstraite n'est plus pure, et plus une interface . Je pense que le VMT a moins d'indirection lorsque l'héritage multiple utilise uniquement des bases abstraites pures, mais je ne me souviens plus à quoi elles ressemblent, depuis trop longtemps.
Jim

Réponses:


2255

Interfaces

Une interface est un contrat : la personne qui écrit l'interface dit: " hé, j'accepte les choses de cette façon ", et la personne qui utilise l'interface dit " OK, la classe que j'écris ressemble à ça" ".

Une interface est un shell vide . Il n'y a que les signatures des méthodes, ce qui implique que les méthodes n'ont pas de corps. L'interface ne peut rien faire. C'est juste un modèle.

Par exemple (pseudo code):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }


    int getFuel()
    {
        return this.fuel;
    }
}

L'implémentation d'une interface consomme très peu de CPU, car ce n'est pas une classe, juste un tas de noms, et donc il n'y a pas de recherche coûteuse à faire. C'est super quand c'est important, comme dans les appareils embarqués.


Classes abstraites

Les classes abstraites, contrairement aux interfaces, sont des classes. Ils sont plus chers à utiliser, car il y a une recherche à faire lorsque vous en héritez.

Les classes abstraites ressemblent beaucoup à des interfaces, mais elles ont quelque chose de plus: vous pouvez leur définir un comportement. Il s'agit plus d'une personne qui dit: " Ces cours devraient ressembler à ça, et ils ont ça en commun, alors remplissez les blancs! ".

Par exemple:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

la mise en oeuvre

Alors que les classes abstraites et les interfaces sont supposées être des concepts différents, les implémentations rendent cette déclaration parfois fausse. Parfois, ils ne sont même pas ce que vous pensez qu'ils sont.

En Java, cette règle est fortement appliquée, tandis qu'en PHP, les interfaces sont des classes abstraites sans méthode déclarée.

En Python, les classes abstraites sont plus une astuce de programmation que vous pouvez obtenir à partir du module ABC et utilisent en fait des métaclasses, et donc des classes. Et les interfaces sont plus liées au typage canard dans ce langage et c'est un mélange entre les conventions et les méthodes spéciales qui appellent des descripteurs (les méthodes __method__).

Comme d'habitude avec la programmation, il y a de la théorie, de la pratique et de la pratique dans une autre langue :-)


6
Le point clé sur les interfaces n'est pas tant qu'elles disent ce qu'une classe fait, mais permettent aux objets qui peuvent Wizzle de se rendre utiles au code qui a besoin d'un Wizzler. Notez que dans de nombreux cas, ni la personne qui écrit la chose qui peut Wizzle, ni la personne qui a besoin d'un Wizzler, ne sera la personne qui écrit l'interface.
supercat

187
Je ne pense pas que la consommation du processeur soit le point fort sur les interfaces.
Dan Lugg

5
@ e-satis Pouvez-vous expliquer votre point de vue sur l'utilisation du processeur? Pourquoi la classe abstraite étant une classe augmente-t-elle l'utilisation du processeur? À quel type de recherche faites-vous référence ici?
Geek

36
@ e-satis Avec Java 8, vous pouvez définir des méthodes par défaut dans les interfaces, ce qui équivaut à avoir des méthodes non abstraites dans des classes abstraites. Avec cet ajout, je ne peux plus voir la vraie différence entre les classes abstraites et l'interface en plus du fait que je devrais utiliser des interfaces car les classes peuvent implémenter plusieurs interfaces mais ne peuvent hériter qu'une seule classe
Ogen

23
Je pense que la comparaison entre interfaceet classde Head First Javaest vivanteA class defines who you are, and an interface tells what roles you could play
LittleLittleQ

872

Les principales différences techniques entre une classe abstraite et une interface sont les suivantes:

  • Les classes abstraites peuvent avoir des constantes, des membres, des stubs de méthode (méthodes sans corps) et des méthodes définies , tandis que les interfaces ne peuvent avoir que des stubs de constantes et de méthodes .

  • Les méthodes et les membres d'une classe abstraite peuvent être définis avec n'importe quelle visibilité , alors que toutes les méthodes d'une interface doivent être définies comme public(elles sont définies publiques par défaut).

  • Lorsqu'elle hérite d'une classe abstraite, une classe enfant concrète doit définir les méthodes abstraites , tandis qu'une classe abstraite peut étendre une autre classe abstraite et les méthodes abstraites de la classe parente n'ont pas à être définies.

  • De même, une interface étendant une autre interface n'est pas responsable de l'implémentation de méthodes à partir de l'interface parent. En effet, les interfaces ne peuvent définir aucune implémentation.

  • Une classe enfant ne peut étendre qu'une seule classe (abstraite ou concrète), tandis qu'une interface peut s'étendre ou qu'une classe peut implémenter plusieurs autres interfaces .

  • Une classe enfant peut définir des méthodes abstraites avec une visibilité identique ou moins restrictive , tandis qu'une classe implémentant une interface doit définir les méthodes avec la même visibilité exacte (publique).


123
Je pense que c'est la meilleure réponse car elle met en évidence toutes les différences clés. un exemple n'est pas vraiment nécessaire.
Joshua K

4
Et normalement, avec les classes, vous pouvez instancier un objet à partir de celui-ci contrairement aux classes abstraites qui CANNOTdoivent être instanciées.
SASM

Je pensais qu'une classe qui implémentait l'interface devait définir toutes les méthodes de l'interface?
Utilisateur Jiazzy

@Jiazzyuser Si une classe abstraite implémente une interface, elle n'a pas besoin de définir réellement les méthodes de l'interface. Cette exigence peut être reportée aux classes héritées / enfants concrètes. Cependant, une classe concrète doit implémenter toutes les méthodes d'interface qui ne sont pas implémentées par sa classe parente. J'ajouterai un exemple pour illustrer ce point.
Justin Johnson

5
"Lorsqu'elle hérite d'une classe abstraite, la classe enfant doit définir les méthodes abstraites, alors qu'une interface peut étendre une autre interface et les méthodes n'ont pas à être définies." - Ce n'est pas vrai. Tout comme une interface peut étendre une interface sans définir de méthodes, une classe abstraite peut hériter d'une classe abstraite sans définir de méthodes.
Nick

141

Une interface ne contient que la définition / signature de la fonctionnalité, et si nous avons des fonctionnalités communes ainsi que des signatures communes, nous devons utiliser une classe abstraite. En utilisant une classe abstraite, nous pouvons fournir à la fois le comportement et la fonctionnalité à la fois. Un autre développeur héritant de la classe abstraite peut facilement utiliser cette fonctionnalité, car ils n'auraient qu'à remplir les blancs.

entrez la description de l'image ici Pris à partir de:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html


17
Vous devez dire à quel langage cela s'applique ("La classe abstraite ne prend pas en charge l'héritage multiple" est loin d'être universellement vraie)
Ben Voigt

La dernière comparaison est déroutante selon le tableau! Les méthodes dans l'interface ne peuvent pas être statiques mais les variables sont statiques finales Les méthodes implémentées dans la classe abstraite peuvent être statiques
realPK

8
Le membre de l'interface doit être statique final. La dernière déclaration est fausse.
Jawad Zeb

Je pense que «fonctionnalité» dans cette réponse signifie «mise en œuvre». Vous ne savez pas ce que signifie «comportement» - peut-être «signatures»?
LarsH

2
Quel est le langage de programmation ciblé ici? C #?
Peter Mortensen

80

Une explication peut être trouvée ici: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

Une classe abstraite est une classe qui n'est implémentée que partiellement par le programmeur. Il peut contenir une ou plusieurs méthodes abstraites. Une méthode abstraite est simplement une définition de fonction qui sert à dire au programmeur que la méthode doit être implémentée dans une classe enfant.

Une interface est similaire à une classe abstraite; en effet, les interfaces occupent le même espace de noms que les classes et les classes abstraites. Pour cette raison, vous ne pouvez pas définir une interface avec le même nom qu'une classe. Une interface est une classe entièrement abstraite; aucune de ses méthodes n'est implémentée et au lieu d'une sous-classe de classe, elle est censée implémenter cette interface.

Quoi qu'il en soit, je trouve cette explication des interfaces quelque peu confuse. Une définition plus courante est: Une interface définit un contrat que les classes d'implémentation doivent remplir. Une définition d'interface se compose de signatures de membres publics, sans aucun code d'implémentation.


4
C'est la réponse la plus correcte, car les interfaces PHP diffèrent des autres langages en ce sens que les interfaces PHP SONT des classes abstraites sous le capot, tandis que les interfaces des autres langages sont des signatures auxquelles les classes doivent correspondre. Ils se comportent de la même manière tant qu'il n'y a pas d'erreurs.
Tor Valamo

1
Certes, pour PHP, c'est la meilleure réponse. Mais il est plus difficile d'obtenir à partir du blob de texte qu'à partir d'un simple extrait.
e-satis

D'après les définitions que vous avez fournies, elles se ressemblent à l'exception d'un détail: et l'interface est 100% abstraite, tandis qu'une classe abstraite est partiellement abstraite et peut avoir certaines implémentations de méthode (peut-être que toutes les méthodes peuvent avoir des implémentations?).
jww

41

Je ne veux pas souligner les différences, qui ont déjà été dites dans de nombreuses réponses (concernant les modificateurs finaux statiques publics pour les variables dans l'interface et le support des méthodes privées et protégées dans les classes abstraites)

En termes simples, je voudrais dire:

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

De la documentation Oracle

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 non liés peuvent implémenter une Serializableinterface.
  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.

la classe abstraite établit "est une" relation avec les classes concrètes. l'interface fournit une capacité "a" pour les classes.

Si vous recherchez Javaun langage de programmation, voici quelques mises à jour supplémentaires:

Java 8 a réduit l'écart entre les classes interfaceet abstractdans une certaine mesure en fournissant une defaultfonctionnalité de méthode. Une interface n'a pas d'implémentation car une méthode n'est plus valide maintenant.

Reportez-vous à cette page de documentation pour plus de détails.

Jetez un oeil à cette question SE pour des exemples de code pour mieux comprendre.

Comment aurais-je dû expliquer la différence entre une interface et une classe abstraite?


38

Quelques différences importantes:

Sous forme de tableau:

Différence

Comme l'a déclaré Joe de javapapers :

1.La principale différence est que les méthodes d'une interface Java sont implicitement abstraites et ne peuvent pas avoir d'implémentations. Une classe abstraite Java peut avoir des méthodes d'instance qui implémentent un comportement par défaut.

2.Les variables déclarées dans une interface Java sont par défaut finales. Une classe abstraite peut contenir des variables non finales.

3.Les membres d'une interface Java sont publics par défaut. Une classe abstraite Java peut avoir les saveurs habituelles des membres de la classe comme privé, protégé, etc.

4. L'interface Java doit être implémentée à l'aide du mot clé «implements»; Une classe abstraite Java doit être étendue à l'aide du mot-clé «extend».

5.Une interface peut étendre une autre interface Java uniquement, une classe abstraite peut étendre une autre classe Java et implémenter plusieurs interfaces Java.

6.Une classe Java peut implémenter plusieurs interfaces mais elle ne peut étendre qu'une seule classe abstraite.

7. L'interface est absolument abstraite et ne peut pas être instanciée; Une classe abstraite Java ne peut pas non plus être instanciée, mais peut être invoquée s'il existe un main ().

8.En comparaison avec les classes abstraites java, les interfaces java sont lentes car elles nécessitent une indirection supplémentaire.


3
J'ai modifié votre réponse pour fournir une attribution correcte. Vous ne pouvez pas simplement déposer un lien au bas de votre réponse. Vous devez également citer toute la langue copiée à partir d'une autre source. De plus, si ce tableau a été tiré de quelque part, vous devez clairement indiquer d'où il provient.
Brad Larson

Veuillez également mentionner le C ++ ... bien qu'il n'y ait pas de mot-clé "interface" en C ++ en tant que tel, mais c'est aussi un Qn regd C ++ fréquemment demandé.
cbinder

@cbinder: Il n'y a pas de mot-clé 'interface' en c ++. Pour les différences en c ++, veuillez vous référer à 1. tutorialspoint.com/cplusplus/cpp_interfaces.htm 2. tutorialspoint.com/cplusplus/cpp_interfaces.htm
softmage99

@MageshBabu Peut-être que la définition d'une fonction dans une classe contenant une fonction virtuelle pure en fait une classe abstraite plutôt que l'interface
cbinder

2
Avec Java 8, les différences sont moindres maintenant. Vérifiez les différences mises à jour ici: journaldev.com/1607/…
Pankaj

31

Le point principal est que:

  • Le résumé est orienté objet . Il offre les données de base qu'un «objet» devrait avoir et / ou les fonctions qu'il devrait être en mesure de faire. Il s'intéresse aux caractéristiques de base de l'objet: ce qu'il a et ce qu'il peut faire. Par conséquent, les objets qui héritent de la même classe abstraite partagent les caractéristiques de base (généralisation).
  • L'interface est orientée fonctionnalité . Il définit les fonctionnalités qu'un objet doit avoir. Quel que soit l'objet, tant qu'il peut faire ces fonctionnalités, qui sont définies dans l'interface, ça va. Il ignore tout le reste. Un objet / classe peut contenir plusieurs (groupes de) fonctionnalités; il est donc possible pour une classe d'implémenter plusieurs interfaces.

Merci maintenant, nous arrivons quelque part avec une bonne réponse de haut niveau. C'est drôle à quel point dans les commentaires vous devez aller pour trouver une réponse plus compréhensive.
Andrew

1
Les autres réponses sont trop techniques. Cela tend vers ce que je ressentirais comme une «bonne» réponse. Le point entier de la POO est la sémantique, et le fait que des getters publics de classes imbriquées privées soient invoqués via des recherches coûteuses pour le processeur est à peu près hors de propos ici
Sentinel

26

Lorsque vous souhaitez fournir un comportement polymorphe dans une hiérarchie d'héritage, utilisez des classes abstraites.

Lorsque vous souhaitez un comportement polymorphe pour des classes complètement indépendantes, utilisez une interface.


24

Je construis un immeuble de 300 étages

L' interface du plan du bâtiment

  • Par exemple, Servlet (I)

Bâtiment construit jusqu'à 200 étages - partiellement achevé --- résumé

  • Implémentation partielle, par exemple, servlet générique et HTTP

Construction du bâtiment terminée - béton

  • Implémentation complète, par exemple, propre servlet

Interface

  • Nous ne savons rien de la mise en œuvre, juste des exigences. Nous pouvons opter pour une interface.
  • Chaque méthode est publique et abstraite par défaut
  • C'est une classe abstraite 100% pure
  • Si nous déclarons public, nous ne pouvons pas déclarer privé et protégé
  • Si nous déclarons abstrait, nous ne pouvons pas déclarer final, statique, synchronisé, strictfp et natif
  • Chaque interface est publique, statique et finale
  • La sérialisation et les transitoires ne sont pas applicables, car nous ne pouvons pas créer d'instance pour l'interface
  • Non volatile car il est final
  • Chaque variable est statique
  • Lorsque nous déclarons une variable à l'intérieur d'une interface, nous devons initialiser les variables lors de la déclaration
  • Instance et bloc statique non autorisés

Abstrait

  • Mise en œuvre partielle
  • Il a une méthode abstraite. Un ajout, il utilise du béton
  • Aucune restriction pour les modificateurs de méthode de classe abstraite
  • Aucune restriction pour les modificateurs de variables de classe abstraite
  • Nous ne pouvons pas déclarer d'autres modificateurs à l'exception du résumé
  • Aucune restriction pour initialiser les variables

Tiré du site Web de DurgaJobs


Une classe abstraite peut avoir un constructeur
vimal krishna

4
Je suis totalement en désaccord avec ce point de vue. Le plan directeur est un concept complètement différent de celui d '«interface». Blueprint est plus analogue à un modèle statique ou à une spécification de conception pour une implémentation spécifique. Il est plus proche de la «classe», car le plan peut être instancié plusieurs fois via son constructeur, mais même cela n'est pas assez proche car la «classe» contient également la spécification sur la façon de construire (le ctor) et les moyens de le faire. donc. L'interface en tant que concept est destinée à représenter certains comportements, tels que le réchauffement / refroidissement, qui peuvent être appliqués à un éventail de choses, par exemple: les bâtiments, les fours, etc.
Sentinel

18

Travaillons à nouveau sur cette question:

La première chose à vous faire savoir est que 1/1 et 1 * 1 ont les mêmes résultats, mais cela ne signifie pas que la multiplication et la division sont identiques. De toute évidence, ils entretiennent de bonnes relations, mais attention, vous êtes tous les deux différents.

Je soulignerai les principales différences, et le reste a déjà été expliqué:

Les classes abstraites sont utiles pour modéliser une hiérarchie de classes. À première vue de toute exigence, nous savons partiellement ce qui doit être construit, mais nous savons quoi construire. Et donc vos classes abstraites sont vos classes de base.

Les interfaces sont utiles pour permettre à d'autres hiérarchies ou classes de savoir ce que je suis capable de faire. Et quand vous dites que je suis capable de quelque chose, vous devez avoir cette capacité. Les interfaces le marqueront comme obligatoire pour qu'une classe implémente les mêmes fonctionnalités.


2
Bonne réponse, mais la métaphore mathématique est inutile et m'a fait perdre environ une quantité équivalente de temps à la lire en écrivant ce commentaire. Multipliez maintenant cela par toutes les autres personnes qui ont lu cette question.
Andrew

"la métaphore mathématique est inutile", pourquoi pensez-vous que oui?
Dhananjay

12

C'est assez simple en fait.

Vous pouvez considérer une interface comme une classe qui ne peut avoir que des méthodes abstraites et rien d'autre.

Une interface ne peut donc que «déclarer» et non définir le comportement que vous souhaitez que la classe ait.

Une classe abstraite vous permet à la fois de déclarer (en utilisant des méthodes abstraites) et de définir (en utilisant des implémentations de méthodes complètes) le comportement que vous souhaitez que la classe ait.

Et une classe régulière vous permet uniquement de définir, et non de déclarer, le comportement / les actions que vous souhaitez que la classe ait.

Une dernière chose,

En Java, vous pouvez implémenter plusieurs interfaces, mais vous ne pouvez en étendre qu'une (classe abstraite ou classe) ...

Cela signifie que l'héritage d'un comportement défini est limité pour n'en autoriser qu'un par classe ... c.-à-d. Si vous vouliez une classe qui encapsulait le comportement des classes A, B et C, vous auriez besoin de faire ce qui suit: La classe A étend B, la classe C étend A .. c'est un peu un moyen détourné d'avoir un héritage multiple ...

Les interfaces d'autre part, vous pourriez simplement faire: l'interface C implémente A, B

Donc, en fait, Java prend en charge l'héritage multiple uniquement dans les "comportements déclarés", c'est-à-dire les interfaces, et uniquement l'héritage unique avec un comportement défini .. à moins que vous ne fassiez le tour que j'ai décrit ...

J'espère que cela a du sens.


11

La comparaison entre l'interface et la classe abstraite est erronée. Il devrait y avoir deux autres comparaisons à la place: 1) interface vs classe et 2) abstrait vs classe finale .

Interface vs classe

L'interface est un contrat entre deux objets. Par exemple, je suis un facteur et vous êtes un colis à livrer. J'attends de vous que vous connaissiez votre adresse de livraison. Quand quelqu'un me donne un colis, il doit connaître son adresse de livraison:

interface Package {
  String address();
}

La classe est un groupe d'objets qui obéissent au contrat. Par exemple, je suis une boîte du groupe "Boîte" et j'obéis au contrat exigé par le facteur. En même temps j'obéis à d'autres contrats:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Résumé vs final

La classe abstraite est un groupe d'objets incomplets. Ils ne peuvent pas être utilisés, car ils manquent certaines parties. Par exemple, je suis une boîte abstraite compatible GPS - je sais comment vérifier ma position sur la carte:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Cette classe, si elle est héritée / étendue par une autre classe, peut être très utile. Mais en soi - c'est inutile, car il ne peut pas avoir d'objets. Les classes abstraites peuvent être des éléments de construction des classes finales.

La classe finale est un groupe d'objets complets, qui peuvent être utilisés, mais ne peuvent pas être modifiés. Ils savent exactement comment travailler et quoi faire. Par exemple, je suis une Box qui va toujours à l'adresse indiquée lors de sa construction:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

Dans la plupart des langages, comme Java ou C ++, il est possible d'avoir juste une classe , ni abstraite ni finale. Une telle classe peut être héritée et instanciée. Je ne pense pas que cela soit strictement conforme au paradigme orienté objet, cependant.

Encore une fois, la comparaison des interfaces avec les classes abstraites n'est pas correcte.


9

En bref, les différences sont les suivantes:

Différences syntaxiques entre l' interface et la classe abstraite :

  1. Les méthodes et les membres d'une classe abstraite peuvent avoir n'importe quelle visibilité. Toutes les méthodes d'une interface doivent être publiques . // Ne tient plus vrai de Java 9
  2. Une classe enfant concrète d'une classe abstraite doit définir toutes les méthodes abstraites. Une classe enfant abstraite peut avoir des méthodes abstraites. Une interface étendant une autre interface n'a pas besoin de fournir une implémentation par défaut pour les méthodes héritées de l'interface parent.
  3. Une classe enfant ne peut étendre qu'une seule classe. Une interface peut étendre plusieurs interfaces. Une classe peut implémenter plusieurs interfaces.
  4. Une classe enfant peut définir des méthodes abstraites avec une visibilité identique ou moins restrictive, tandis que la classe implémentant une interface doit définir toutes les méthodes d'interface comme publiques.
  5. Les classes abstraites peuvent avoir des constructeurs mais pas des interfaces .
  6. Les interfaces de Java 9 ont des méthodes statiques privées.

Dans Interfaces maintenant:

public static- pris en
public abstractcharge
public default- pris en charge - pris en charge - pris en
private staticcharge
private abstract- erreur de
private defaultcompilation
private- erreur de compilation - pris en charge


8

La seule différence est que l'un peut participer à plusieurs héritages et d'autres non.

La définition d'une interface a changé au fil du temps. Pensez-vous qu'une interface n'a que des déclarations de méthode et ne sont que des contrats? Qu'en est-il des variables finales statiques et des définitions par défaut après Java 8?

Les interfaces ont été introduites dans Java en raison du problème du diamant avec l'héritage multiple et c'est ce qu'elles ont réellement l'intention de faire.

Les interfaces sont les constructions qui ont été créées pour éviter le problème d'héritage multiple et peuvent avoir des méthodes abstraites, des définitions par défaut et des variables finales statiques.

Voir Pourquoi Java autorise-t-il les variables finales statiques dans les interfaces alors qu'elles ne sont destinées qu'à être des contrats? .


1
Bien que ce soit une différence importante , ce n'est pas la seule différence.
Govind Parmar

7

Interface: tourner (tourner à gauche, tourner à droite.)

Classe abstraite: roue.

Classe: volant, dérive de la roue, expose le virage d'interface

L'un est pour catégoriser les comportements qui peuvent être proposés à travers une gamme variée de choses, l'autre est pour modéliser une ontologie des choses.


6

Si vous avez des méthodes communes qui peuvent être utilisées par plusieurs classes, optez pour des classes abstraites. Sinon, si vous voulez que les classes suivent un plan défini, optez pour les interfaces.

Les exemples suivants le démontrent.

Classe abstraite en Java:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

Voici une implémentation de l'interface en Java:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Quelques points clés importants en bref:

  1. Les variables déclarées dans l'interface Java sont par défaut finales. Les classes abstraites peuvent avoir des variables non finales.

  2. Les variables déclarées dans l'interface Java sont par défaut statiques. Les classes abstraites peuvent avoir des variables non statiques.

  3. Les membres d'une interface Java sont publics par défaut. Une classe abstraite Java peut avoir les saveurs habituelles des membres de la classe comme privé, protégé, etc.


4

De nombreux développeurs juniors font l'erreur de considérer les interfaces, les classes abstraites et concrètes comme de légères variations de la même chose, et choisissent l'une d'entre elles uniquement pour des raisons techniques: ai-je besoin d'un héritage multiple? Ai-je besoin d'un endroit pour mettre des méthodes communes? Dois-je m'embêter avec autre chose qu'un cours concret? C'est faux, et le problème principal est caché dans ces questions: "Je" . Lorsque vous écrivez du code pour vous-même, vous pensez rarement à d'autres développeurs actuels ou futurs travaillant sur ou avec votre code.

Les interfaces et les classes abstraites, bien qu'apparemment similaires d'un point de vue technique, ont des significations et des objectifs complètement différents.

Sommaire

  1. Une interface définit un contrat qu'une certaine implémentation remplira pour vous .

  2. Une classe abstraite fournit un comportement par défaut que votre implémentation peut réutiliser.

Résumé alternatif

  1. Une interface permet de définir des API publiques
  2. Une classe abstraite est à usage interne et pour définir des SPI

Sur l'importance de masquer les détails de la mise en œuvre

Une classe concrète fait le travail réel, d'une manière très spécifique. Par exemple, an ArrayListutilise une zone de mémoire contiguë pour stocker une liste d'objets de manière compacte qui offre un accès aléatoire rapide, une itération et des modifications sur place, mais est terrible lors des insertions, des suppressions et parfois même des ajouts; pendant ce temps, unLinkedList utilise des nœuds à double liaison pour stocker une liste d'objets, qui offre à la place une itération rapide, des modifications sur place et une insertion / suppression / addition, mais est terrible à l'accès aléatoire. Ces deux types de listes sont optimisés pour différents cas d'utilisation, et la façon dont vous allez les utiliser importe beaucoup. Lorsque vous essayez d'extraire les performances d'une liste avec laquelle vous interagissez fortement, et lorsque vous choisissez le type de liste, vous devez soigneusement choisir celle que vous instanciez.

D'un autre côté, les utilisateurs de haut niveau d'une liste ne se soucient pas vraiment de la façon dont elle est réellement mise en œuvre, et ils doivent être isolés de ces détails. Imaginons que Java n'ait pas exposé l' Listinterface, mais n'avait qu'une Listclasse concrète qui est en fait ce qui LinkedListest en ce moment. Tous les développeurs Java auraient adapté leur code pour s'adapter aux détails de l'implémentation: éviter l'accès aléatoire, ajouter un cache pour accélérer l'accès, ou simplement réimplémenter ArrayListpar eux-mêmes, bien qu'il soit incompatible avec tous les autres codes qui fonctionnent réellement avecList . Ce serait terrible ... Mais imaginez maintenant que les maîtres Java réalisent réellement qu'une liste chaînée est terrible pour la plupart des cas d'utilisation réels, et ont décidé de passer à une liste de tableaux pour leur seulListclasse disponible. Cela affecterait les performances de chaque programme Java dans le monde, et les gens n'en seraient pas satisfaits. Et le principal coupable est que les détails de l'implémentation étaient disponibles, et les développeurs ont supposé que ces détails étaient un contrat permanent sur lequel ils pouvaient s'appuyer. C'est pourquoi il est important de masquer les détails de l'implémentation et de définir uniquement un contrat abstrait. C'est le but d'une interface: définir le type d'entrée qu'une méthode accepte et le type de sortie attendu, sans exposer tous les tripes qui inciteraient les programmeurs à modifier leur code pour s'adapter aux détails internes qui pourraient changer avec toute mise à jour future .

Une classe abstraite se situe entre les interfaces et les classes concrètes. Il est censé aider les implémentations à partager du code commun ou ennuyeux. Par exemple, AbstractCollectionfournit des implémentations de isEmptybase pour basées sur la taille est 0, containscomme itérer et comparer, addAllcomme répété add, et ainsi de suite. Cela permet aux implémentations de se concentrer sur les parties cruciales qui les différencient: comment réellement stocker et récupérer des données.

API versus SPI

Les interfaces sont des passerelles à faible cohésion entre différentes parties du code. Ils permettent aux bibliothèques d'exister et d'évoluer sans casser chaque utilisateur de bibliothèque lorsque quelque chose change en interne. C'est ce qu'on appelle l' interface de programmation d'application , pas les classes de programmation d'application. À plus petite échelle, ils permettent également à plusieurs développeurs de collaborer avec succès sur des projets à grande échelle, en séparant différents modules via des interfaces bien documentées.

Les classes abstraites sont des aides à haute cohésion à utiliser lors de l'implémentation d'une interface, en supposant un certain niveau de détails d'implémentation. Alternativement, des classes abstraites sont utilisées pour définir des SPI, des interfaces de fournisseur de services.

La différence entre une API et un SPI est subtile, mais importante: pour une API, l'accent est mis sur qui l' utilise et pour un SPI, l'accent est mis sur qui l' implémente .

L'ajout de méthodes à une API est facile, tous les utilisateurs existants de l'API seront toujours compilés. L'ajout de méthodes à un SPI est difficile, car chaque fournisseur de services (implémentation concrète) devra implémenter les nouvelles méthodes. Si des interfaces sont utilisées pour définir un SPI, un fournisseur devra publier une nouvelle version chaque fois que le contrat SPI change. Si des classes abstraites sont utilisées à la place, de nouvelles méthodes pourraient être définies en termes de méthodes abstraites existantes, ou en tant que throw not implemented exceptionstubs vides , ce qui permettra au moins à une ancienne version d'une implémentation de service de compiler et d'exécuter.

Une note sur Java 8 et les méthodes par défaut

Bien que Java 8 ait introduit des méthodes par défaut pour les interfaces, ce qui rend la ligne entre les interfaces et les classes abstraites encore plus floue, ce n'était pas pour que les implémentations puissent réutiliser le code, mais pour faciliter la modification des interfaces qui servent à la fois d'API et de SPI (ou sont mal utilisés pour définir des SPI au lieu de classes abstraites).

Lequel utiliser?

  1. La chose est-elle censée être utilisée publiquement par d'autres parties du code ou par un autre code externe? Ajoutez-y une interface pour masquer les détails d'implémentation du contrat abstrait public, qui est le comportement général de la chose.
  2. Est la chose est-elle censée avoir plusieurs implémentations avec beaucoup de code en commun? Créez à la fois une interface et une implémentation abstraite et incomplète.
  3. Y aura-t-il jamais une seule implémentation, et personne d'autre ne l'utilisera? Faites-en une classe concrète.
    1. "ever" est long, vous pouvez jouer en toute sécurité et ajouter une interface par-dessus.

Un corollaire: l'inverse est souvent mal fait: lorsque vous utilisez une chose , essayez toujours d'utiliser la classe / interface la plus générique dont vous avez réellement besoin. En d'autres termes, ne déclarez pas vos variables comme ArrayList theList = new ArrayList(), sauf si vous avez en fait une très forte dépendance à ce qu'il s'agisse d'une liste de tableaux , et aucun autre type de liste ne la couperait pour vous. Utilisez-le à la List theList = new ArrayListplace, ou même Collection theCollection = new ArrayListsi le fait qu'il s'agisse d'une liste, et qu'aucun autre type de collection n'ait vraiment d'importance.


4

Pas vraiment la réponse à la question d'origine, mais une fois que vous aurez la réponse à la différence entre eux, vous entrerez dans le dilemme de l'utilisation de chaque: quand utiliser des interfaces ou des classes abstraites? Quand utiliser les deux?

J'ai une connaissance limitée de la POO, mais voir les interfaces comme un équivalent d'un adjectif en grammaire a fonctionné pour moi jusqu'à présent (corrigez-moi si cette méthode est fausse!). Par exemple, les noms d'interface sont comme des attributs ou des capacités que vous pouvez attribuer à une classe, et une classe peut en avoir plusieurs: ISerializable, ICountable, IList, ICacheable, IHappy, ...


3

L'héritage est utilisé à deux fins:

  • Pour permettre à un objet de considérer les membres de données de type parent et les implémentations de méthode comme les siens.

  • Pour permettre à une référence à des objets d'un type d'être utilisée par du code qui attend une référence à un objet de type supérieur.

Dans les langages / cadres qui prennent en charge l'héritage multiple généralisé, il n'est souvent pas nécessaire de classer un type comme étant une "interface" ou une "classe abstraite". Cependant, les langages et cadres populaires permettront à un type de considérer les membres de données ou les implémentations de méthode d'un autre type comme les siens, même s'ils permettent à un type d'être substituable à un nombre arbitraire d'autres types.

Les classes abstraites peuvent avoir des membres de données et des implémentations de méthode, mais ne peuvent être héritées que par des classes qui n'héritent d'aucune autre classe. Les interfaces ne mettent presque aucune restriction sur les types qui les implémentent, mais ne peuvent inclure aucun membre de données ou implémentation de méthode.

Il y a des moments où il est utile que les types soient substituables à de nombreuses choses différentes; il y a d'autres moments où il est utile que les objets considèrent les membres de données de type parent et les implémentations de méthode comme les leurs. Faire une distinction entre les interfaces et les classes abstraites permet à chacune de ces capacités d'être utilisée dans les cas où elle est la plus pertinente.


3

Points clés:

  • La classe abstraite peut avoir des propriétés, des champs de données, des méthodes (complètes / incomplètes).
  • Si la méthode ou les propriétés définissent dans un mot clé abstrait qui doit remplacer dans la classe dérivée (son travail en tant que fonctionnalité étroitement couplée)
  • Si définir un mot clé abstrait pour la méthode ou les propriétés dans la classe abstraite, vous ne pouvez pas définir le corps de la méthode et obtenir / définir la valeur des propriétés et cela doit remplacer dans la classe dérivée.
  • La classe abstraite ne prend pas en charge l'héritage multiple.
  • La classe abstraite contient des constructeurs.
  • Une classe abstraite peut contenir des modificateurs d'accès pour les sous-marins, les fonctions et les propriétés.
  • Seul un membre complet de la classe abstraite peut être statique.
  • Une interface peut hériter d'une autre interface uniquement et ne peut pas hériter d'une classe abstraite, alors qu'une classe abstraite peut hériter d'une autre classe abstraite ou d'une autre interface.

Avantage:

  • C'est une sorte de contrat qui oblige toutes les sous-classes à poursuivre les mêmes hiérarchies ou normes.
  • Si diverses implémentations sont du même type et utilisent un comportement ou un état commun, il est préférable d'utiliser la classe abstraite.
  • Si nous ajoutons une nouvelle méthode à une classe abstraite, nous avons la possibilité de fournir une implémentation par défaut et donc tout le code existant pourrait fonctionner correctement.
  • Il permet une exécution plus rapide que l'interface (l'interface nécessite plus de temps pour trouver la méthode réelle dans les classes correspondantes).
  • Il peut être utilisé pour un couplage serré et lâche.

trouvez les détails ici ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/


3

Le moyen le plus court de le résumer est que an interfaceest:

  1. Entièrement abstrait, à part defaultet staticméthodes; bien qu'il ait des définitions (signatures de méthodes + implémentations) pour les méthodes defaultet static, il n'a que des déclarations (signatures de méthodes) pour les autres méthodes.
  2. Soumis à des règles plus laxistes que les classes (une classe peut implémenter plusieurs interfaces et une interfacepeut hériter de plusieurs interfaces). Toutes les variables sont implicitement constantes, qu'elles soient spécifiées public static finalou non. Tous les membres sont implicitement public, qu'ils soient spécifiés comme tels ou non.
  3. Généralement utilisé comme garantie que la classe d'implémentation aura les fonctionnalités spécifiées et / ou sera compatible avec toute autre classe qui implémente la même interface.

Pendant ce temps, une abstractclasse est:

  1. Partout de l'abstrait à l'implémentation complète, avec une tendance à avoir une ou plusieurs abstractméthodes. Peut contenir à la fois des déclarations et des définitions, avec des déclarations marquées commeabstract .
  2. Une classe à part entière, et soumise aux règles qui régissent les autres classes (ne peut hériter que d'une classe), à ​​condition qu'elle ne puisse pas être instanciée (car il n'y a aucune garantie qu'elle est entièrement implémentée). Peut avoir des variables membres non constantes. Peut implémenter le contrôle d'accès des membres, restreindre les membres en tant que protected,private ou package privé (non spécifié).
  3. Généralement utilisé soit pour fournir autant d'implémentations que peuvent être partagées par plusieurs sous-classes, soit pour fournir autant d'implémentations que le programmeur est capable de fournir.

Ou, si nous voulons tout résumer en une seule phrase: An interfaceest ce que possède la classe d'implémentation , mais une abstractclasse est ce qu'est la sous - classe .


3

Je voudrais ajouter une différence de plus qui a du sens. Par exemple, vous disposez d'un framework avec des milliers de lignes de code. Maintenant, si vous souhaitez ajouter une nouvelle fonctionnalité dans le code à l'aide d'une méthode enhanUI (), il est préférable d'ajouter cette méthode dans la classe abstraite plutôt que dans l'interface. Parce que, si vous ajoutez cette méthode dans une interface, vous devez l'implémenter dans toute la classe implémentée, mais ce n'est pas le cas si vous ajoutez la méthode dans la classe abstraite.


3

Pour donner une réponse simple mais claire, cela aide à définir le contexte: vous utilisez les deux lorsque vous ne souhaitez pas fournir des implémentations complètes.

La principale différence est donc qu'une interface n'a aucune implémentation (uniquement des méthodes sans corps) tandis que les classes abstraites peuvent également avoir des membres et des méthodes avec un corps, c'est-à-dire qu'elles peuvent être partiellement implémentées.


Puisque vous y avez répondu tout à l'heure, votre réponse ne prend pas en compte le defaultmot clé en Java 8 avec lequel vous pouvez également définir des méthodes concrètes dans les interfaces.
philantrovert

Comme je l'ai dit, cela devait être une "réponse simple mais claire" pour quelqu'un au stade de l'apprentissage de la différence. Pour quelqu'un comme ça, il n'est pas utile de connaître ce genre d'exception, ce ne serait que très déroutant.
user3775501

3

Différences entre la classe abstraite et l'interface au nom d'une implémentation réelle.

Interface : C'est un mot-clé et il est utilisé pour définir le modèle ou l'impression bleue d'un objet et force toutes les sous-classes à suivre le même prototype, comme pour l'implémentation, toutes les sous-classes sont libres d'implémenter la fonctionnalité selon c'est l'exigence.

Certains autres cas d'utilisation où nous devrions utiliser l'interface.

La communication entre deux objets externes (intégration de tiers dans notre application) via l' interface ici Interface fonctionne comme un contrat.

Classe abstraite: abstraite, c'est un mot-clé et lorsque nous utilisons ce mot-clé avant n'importe quelle classe, il devient une classe abstraite.Il est principalement utilisé lorsque nous devons définir le modèle ainsi que certaines fonctionnalités par défaut d'un objet qui est suivi par tous les sous-classes et de cette façon, il supprime le code redondant et un cas d'utilisation de plus où nous pouvons utiliser une classe abstraite , comme nous voulons qu'aucune autre classe ne puisse instancier directement un objet de la classe, seules les classes dérivées peuvent utiliser la fonctionnalité.

Exemple de classe abstraite:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Exemple d'interface:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }

3

Vous pouvez trouver une différence claire entre l' interface et la classe abstraite.

Interface

  • L'interface contient uniquement des méthodes abstraites.
  • Forcer les utilisateurs à implémenter toutes les méthodes lors de l'implémentation de l'interface.
  • Contient uniquement des variables finales et statiques.
  • Déclarez en utilisant le mot-clé d'interface.
  • Toutes les méthodes d'une interface doivent être définies comme publiques.
  • Une interface peut s'étendre ou une classe peut implémenter plusieurs autres interfaces.

Classe abstraite

  • La classe abstraite contient des méthodes abstraites et non abstraites.

  • N'oblige pas les utilisateurs à implémenter toutes les méthodes lorsqu'ils héritent de la classe abstraite.

  • Contient toutes sortes de variables, y compris primitives et non primitives

  • Déclarez en utilisant un mot-clé abstrait.

  • Les méthodes et les membres d'une classe abstraite peuvent être définis avec n'importe quelle visibilité.

  • Une classe enfant ne peut étendre qu'une seule classe (abstraite ou concrète).


2

Une classe abstraite est une classe dont l'objet ne peut pas être créé ou une classe qui ne peut pas être instanciée. Une méthode abstraite rend une classe abstraite. Une classe abstraite doit être héritée afin de remplacer les méthodes déclarées dans la classe abstraite. Aucune restriction sur les spécificateurs d'accès. Une classe abstraite peut avoir un constructeur et d'autres méthodes concrètes (méthodes non abstarctes) mais l'interface ne peut pas en avoir.

Une interface est un plan directeur / modèle de méthodes (par exemple. Une maison sur un papier est donnée (maison d'interface) et différents architectes utiliseront leurs idées pour la construire (les classes d'architectes mettant en œuvre l'interface de maison). Il s'agit d'une collection de méthodes abstraites, méthodes par défaut, méthodes statiques, variables finales et classes imbriquées. Tous les membres seront définitifs ou publics, les spécificateurs d'accès protégés et privés ne sont pas autorisés. Aucune création d'objet n'est autorisée. Une classe doit être créée afin d'utiliser implémentant l'interface et également pour remplacer la méthode abstraite déclarée dans l'interface. Une interface est un bon exemple de couplage lâche (polymorphisme dynamique / liaison dynamique) Une interface implémente le polymorphisme et l'abstraction. Elle indique quoi faire mais comment faire est défini par le classe d'implémentation. Par exemple.sa car company et il veut que certaines fonctionnalités soient les mêmes pour toutes les voitures qu'il fabrique, de sorte que la société fabrique un véhicule d'interface qui aura ces fonctionnalités et différentes classes de voitures (comme Maruti Suzkhi, Maruti 800) qui prévaudront ces caractéristiques (fonctions).

Pourquoi s'interfacer alors que nous avons déjà une classe abstraite? Java ne prend en charge que l'héritage multiniveau et hiérarchique, mais avec l'aide de l'interface, nous pouvons implémenter l'héritage multiple.


2

En termes pratiques (JAVA), la principale différence entre la classe abstraite et l'interface est que la classe abstraite peut contenir un état. Outre l'état de maintien, nous pouvons également réaliser des opérations de repos avec Interface.


1

Dans une interface, toutes les méthodes ne doivent être que des définitions, aucune ne doit être implémentée.

Mais dans une classe abstraite, il doit y avoir une méthode abstraite avec seulement une définition, mais d'autres méthodes peuvent aussi être dans la classe abstraite avec implémentation ...


1

Nous avons différentes différences structurelles / syntaxiques entre l'interface et la classe abstraite. Quelques différences supplémentaires sont

[1] Différence basée sur un scénario :

Les classes abstraites sont utilisées dans les scénarios lorsque nous voulons restreindre l'utilisateur à créer un objet de la classe parent ET nous pensons qu'il y aura plus de méthodes abstraites à l'avenir.

L'interface doit être utilisée lorsque nous sommes sûrs qu'il ne peut plus y avoir de méthode abstraite à fournir. Ensuite, seule une interface est publiée.

[2] Différence conceptuelle :

"Avons-nous besoin de fournir plus de méthodes abstraites à l'avenir" si OUI en fait une classe abstraite et si NON en fait une Interface.

(Le plus approprié et valide jusqu'à Java 1.7)


1

habituellement classe abstraite utilisée pour le noyau de quelque chose mais interface utilisée pour ajouter un périphérique.

lorsque vous souhaitez créer un type de base pour un véhicule, vous devez utiliser une classe abstraite mais si vous souhaitez ajouter des fonctionnalités ou des propriétés qui ne font pas partie du concept de base du véhicule, vous devez utiliser l'interface, par exemple, vous voulez ajouter la fonction "ToJSON ()" .

l'interface a une large gamme d'abstraction plutôt que de classe abstraite. vous pouvez le voir en passant des arguments. regardez cet exemple:

entrez la description de l'image ici

si vous utilisez un véhicule comme argument, vous pouvez simplement utiliser l'un de ses types dérivés (bus ou voiture - même catégorie - catégorie de véhicule uniquement). mais lorsque vous utilisez l'interface IMoveable comme argument, vous avez plus de choix.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.