1968 votes

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

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

112 votes

C'est 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 beaucoup aidé Safraz.

6 votes

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

11 votes

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

2441voto

e-satis Points 146299

Interfaces

Une interface est un contrat : La personne rédigeant l'interface dit, "hey, j'accepte que les choses soient ainsi", et la personne utilisant l'interface dit "D'accord, la classe que j'écris ressemble à ça".

Une interface est une coquille 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 (code pseudo) :

// Je dis que tous les véhicules à moteur devraient ressembler à ça:
interface VehiculeMotorisé
{
    void rouler();

    int getCarburant();
}

// Mon coéquipier se conforme et écrit un véhicule qui ressemble à ça
class Voiture implements VehiculeMotorisé
{

    int carburant;

    void rouler()
    {
        print("Vroum");
    }

    int getCarburant()
    {
        return this.carburant;
    }
}

Implémenter une interface consomme très peu de CPU, car ce n'est pas une classe, juste un ensemble de noms, et donc il n'y a pas de recherche coûteuse à faire. C'est génial quand cela compte, comme dans les appareils embarqués.


Classes abstraites

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

Les classes abstraites ressemblent beaucoup aux interfaces, mais elles ont quelque chose de plus : vous pouvez définir un comportement pour elles. C'est plus une personne disant, "ces classes devraient ressembler à ça, et elles ont ça en commun, alors complétez les vides !".

Par exemple :

// Je dis que tous les véhicules à moteur devraient ressembler à ça:
abstract class VehiculeMotorisé
{

    int carburant;

    // Ils ont TOUS du carburant, donc implémentons cela pour tout le monde.
    int getCarburant()
    {
         return this.carburant;
    }

    // Cela peut être très différent, obligez-les à fournir leur
    // propre implémentation.
    abstract void rouler();
}

// Mon coéquipier se conforme et écrit un véhicule qui ressemble à ça
class Voiture extends VehiculeMotorisé
{
    void rouler()
    {
        print("Vroum");
    }
}

Implémentation

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

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

En Python, les classes abstraites sont davantage un tour de passe-passe que vous pouvez obtenir du module ABC et qui utilise en réalité des métaclasses, et donc des classes. Et les interfaces sont davantage liées au typage canard dans ce langage, c'est un mélange entre des conventions et des méthodes spéciales qui appellent des descripteurs (les méthodes __méthode__).

Comme d'habitude en programmation, il y a la théorie, la pratique, et la pratique dans un autre langage :-)

6 votes

Le point clé concernant les interfaces n'est pas tant qu'elles disent ce qu'une classe fait, mais qu'elles 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 seront la personne qui écrit l'interface.

224 votes

Je ne pense pas que la consommation de CPU soit le point notable sur les interfaces.

1 votes

@AshwinP - voir cette question, plus précisément cette réponse.

956voto

Justin Johnson Points 16243

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

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

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

  • Lorsqu'une classe abstraite est héritée, 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 parent n'ont pas besoin d'être définies.

  • De même, une interface qui étend une autre interface n'est pas responsable de l'implémentation des méthodes de l'interface parente. Cela est dû au fait que les interfaces ne peuvent pas définir d'implémentation.

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

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

136 votes

Je pense que c'est la meilleure réponse car elle met en avant toutes les différences clés. Un exemple n'est pas vraiment nécessaire.

5 votes

Et normalement avec des classes, vous pouvez instancier un objet à partir d'elle contrairement aux classes abstraites qui NE PEUVENT PAS être instanciées.

0 votes

Je pensais qu'une classe qui implémente l'interface doit définir toutes les méthodes de l'interface?

158voto

Vivek Points 641

Une interface contient uniquement la définition / la signature de la fonctionnalité, et si nous avons des fonctionnalités communes ainsi que des signatures communes, alors nous devons utiliser une classe abstraite. En utilisant une classe abstraite, nous pouvons fournir du comportement ainsi que de la fonctionnalité en même temps. Un autre développeur héritant de la classe abstraite peut utiliser cette fonctionnalité facilement, car il lui suffirait de remplir les blancs.

Interface

Classe abstraite

Interface supporte des implémentations multiples.

La classe abstraite ne supporte pas l'héritage multiple.

L'interface ne contient pas de membres de données

La classe abstraite contient des membres de données

L'interface ne contient pas de constructeurs

La classe abstraite contient des constructeurs

Une interface contient uniquement des membres incomplets (signature du membre)

Une classe abstraite contient à la fois des membres incomplets (abstraits) et complets

Une interface ne peut pas avoir de modificateurs d'accès, par défaut tout est considéré comme public

Une classe abstraite peut contenir des modificateurs d'accès pour les sous-programmes, fonctions, propriétés

Les membres de l'interface ne peuvent pas être statiques

Seuls les membres complets de la classe abstraite peuvent être statiques

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

20 votes

Vous devez dire à quelle langue cela s'applique ("La classe abstraite ne prend pas en charge l'héritage multiple" est loin d'être universellement vrai)

0 votes

La dernière comparaison est confuse selon le tableau! Les méthodes dans une interface ne peuvent pas être statiques mais les variables sont statiques finales. Les méthodes implémentées dans une classe abstraite peuvent être statiques.

12 votes

Les membres de l'interface doivent être statiques finaux. La dernière déclaration est incorrecte.

84voto

Konamiman Points 20578

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 partiellement implémentée par le programmeur. Elle peut contenir une ou plusieurs méthodes abstraites. Une méthode abstraite est simplement une définition de fonction qui indique 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 totalement abstraite; aucune de ses méthodes n'est implémentée et au lieu d'une classe étendue de celle-ci, on dit qu'elle implémente 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 implémentées doivent remplir. La définition d'une interface se compose de signatures de membres publics, sans aucun code d'implémentation.

4 votes

Il s'agit de la réponse la plus correcte, car les interfaces PHP diffèrent des autres langages en ce que les interfaces PHP SONT des classes abstraites sous-jacentes, alors 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 cependant.

1 votes

Vrai, pour PHP c'est la meilleure réponse. Mais c'est plus difficile à obtenir à partir du bloc de texte que d'un simple extrait.

0 votes

À partir des définitions que vous avez fournies, elles se ressemblent à une exception près: une interface est 100% abstraite, alors qu'une classe abstraite est partiellement abstraite et peut avoir des implémentations de certaines méthodes (peut-être que toutes les méthodes peuvent avoir des implémentations?).

42voto

Magesh Babu Points 94

Quelques différences importantes :

Sous forme de tableau :

Différence

Comme indiqué par 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 types habituels de membres de classe comme private, protected, etc..

4. Une interface Java doit être implémentée en utilisant le mot-clé "implements" ; une classe abstraite Java doit être étendue en utilisant le mot-clé "extends".

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. Une interface est totalement 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 si une méthode main() existe.

8. En comparaison avec les classes abstraites Java, les interfaces Java sont plus lentes car elles nécessitent des indirections supplémentaires.

3 votes

J'ai édité votre réponse pour fournir une attribution correcte. Vous ne pouvez pas simplement déposer un lien en bas de votre réponse. Vous devez citer l'intégralité du texte qui a été copié d'une autre source. De plus, si ce tableau a été tiré d'ailleurs, vous devriez clairement indiquer sa provenance.

0 votes

Veuillez mentionner C++ également.. bien qu'il n'y ait pas de mot-clé "interface" en C++ en tant que tel, mais c'est une question couramment posée concernant C++ également.

0 votes

@cbinder: Il n'existe pas de mot-clé 'interface' en c++. Pour plus de différences en c++, veuillez consulter 1. tutorialspoint.com/cplusplus/cpp_interfaces.htm 2. tutorialspoint.com/cplusplus/cpp_interfaces.htm

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X