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 :-)
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.
2 votes
De retour dans le passé en c++, une interface est une classe de base abstraite pure avec toutes les implémentations de méthode = 0. Si une seule méthode n'est pas = 0, alors elle a une implémentation et la base abstraite n'est plus pure, et n'est plus une interface. Je pense que la VMT a moins d'indirection lorsque l'héritage multiple n'utilise que des bases abstraites pures, mais je ne me souviens plus à quoi elles ressemblent, cela fait trop longtemps.
0 votes
En kotlin: Les interfaces ne peuvent pas stocker un état. Seules les classes abstraites peuvent stocker un état.