2010-09-15 4 views
8

Qu'est-ce qu'une classe abstraite et une interface en PHP et quand les utiliseriez-vous? Une réponse profane avec un exemple serait formidable pour aider ma compréhension.Qu'est-ce qu'une CLASSE ABSTRACT et INTERFACE et quand les utiliseriez-vous en PHP?

+0

pourrait vous s'il vous plaît passer par les réponses à vos questions et ce précédentes et accepter les plus utiles ou modifier vos questions à indiquer pourquoi aucune des réponses résoudre votre question. Merci. – Gordon

Répondre

7

classes et interfaces abstraites ne sont pas spécifiques à PHP; ce sont des caractéristiques de nombreux langages orientés objet modernes.

Une classe abstraite est une classe qui possède une ou plusieurs fonctions membres non implémentées. Vous utiliseriez un dans une situation où vous voudriez un ensemble de classes qui ont des comportements similaires, ne différant que par quelques méthodes. Chacune de ces classes dériverait de la classe abstraite et implémenterait les méthodes non implémentées de la manière appropriée à leur cas particulier.

Une interface est similaire à une classe abstraite, mais elle ne contient aucune implémentation de méthode, seulement des signatures. Une classe qui implémente une interface doit implémenter toutes les méthodes.

Une classe peut implémenter de nombreuses interfaces, mais ne peut être dérivée que d'une classe abstraite (ou d'une classe parente de n'importe quel type), puisque PHP ne supporte pas l'héritage multiple.

Les classes abstraites et les interfaces permettent le polymorphisme; c'est-à-dire que vous pouvez spécifier une référence comme étant un type abstrait (qui peut se référer à n'importe quelle instance de classe dérivée) ou à un objet implémentant une interface.

+0

Excellente réponse. Y a-t-il des différences entre être simplement une classe parente et être une classe abstraite? –

+1

@Travis: Oui. Une classe abstraite ne peut pas être instanciée. Je crée occasionnellement des classes abstraites pour partager une fonctionnalité incomplète (en supposant que la relation parent-sous est vraiment une relation 'est-a'). Une fois la sous-classe instanciée, la fonctionnalité complète de la classe/instance est disponible. –

+0

bonne explication. J'ai quelque chose à ajouter ... En PHP et Java, les méthodes de l'interface doivent être publiques. – Alex

0

Une interface définit un ensemble de méthodes qu'une classe doit implémenter. Une telle classe implémente l'interface en fournissant une implémentation concrète de ces méthodes. Une interface ne peut contenir aucune implémentation qui lui soit propre; c'est juste un ensemble de signatures de méthodes. Si je définis une interface appelée ILogger, alors je peux écrire du code qui utilise les méthodes définies dans ILogger (peut-être write et writeLine) pour transmettre les messages à consigner. Je peux passer dans n'importe quelle classe qui implémente ILogger, et c'est pareil pour le code client.

Une classe abstraite est similaire, mais peut implémenter certaines méthodes et certains états. Les classes abstraites ne peuvent pas être instanciées et toute classe qui les étend doit fournir une implémentation de chaque méthode abstract dans la classe parente. Si un ensemble de classes partage des détails d'implémentation mais diffère dans d'autres, vous pouvez définir l'implémentation partagée dans une classe abstraite, déclarer les différentes méthodes abstraites, et laisser les classes enfants remplir celles-ci avec leur propre implémentation. Si je voulais un moyen uniforme pour collecter des informations système, ajouter des horodatages, etc. partagés par tous mes enregistreurs, je pourrais choisir de créer une classe abstraite LoggerBase qui traiterait ces détails, en marquant write et writeLineabstract de sorte que toutes les classes s'étendant LoggerBase juste besoin de spécifier comment écrire dans leur journal particulier.

4

En supposant que vous compreniez pourquoi vous les utilisez dans d'autres langues, les mêmes concepts s'appliquent à PHP. Les interfaces sont des "signatures" de classe ... elles ne contiennent aucun code. Les classes abstraites ne peuvent pas être instanciées, mais elles peuvent contenir à la fois des fonctions implémentées et abstraites (vides).

Notez qu'une classe peut uniquement étendre une classe parent unique (ou une classe abstraite), mais qu'elle peut implémenter autant d'interfaces que nécessaire.Mais étant donné que PHP n'a pas de dactylographie stricte et n'a aucun concept de vérification de temps de compilation, vous pouvez généralement faire sans, contrairement à des langages comme C++ ou Java.

Le noyau PHP nécessite des interfaces pour certaines choses. Par exemple:

class Foo implements Countable 
{ 
    public function count() 
    { 
    return 5; 
    } 
} 

echo count(new Foo()); // returns 5 

Si vous supprimez le « implémente dénombrable, » PHP ne sera pas appeler votre méthode count. Il existe de nombreuses autres interfaces que vous pouvez implémenter et qui permettent à tous les objets personnalisés de se comporter de la même manière. Par exemple, vous pouvez créer un objet qui fonctionne avec une itération foreach.

Les interfaces au niveau de l'utilisateur ne sont pas extrêmement utiles en PHP, comme je l'ai mentionné précédemment. Mais si vous utilisez des notes de type, ils peuvent être:

function foo(MyInterface $bar) 
{ 
    $bar->someMethod(); 
} 

En supposant someMethod est déclaré dans MyInterface, alors vous êtes assuré que l'appel à $bar->someMethod() existe. (La raison pour laquelle cela n'est pas aussi utile en PHP que dans d'autres langues est que l'indicateur de type dans la signature de la fonction ne sera pas vérifié avant l'exécution.)

Les interfaces vides peuvent aussi être utiles catégoriser les classes. Dites que vous voulez faire quelque chose à un ensemble particulier d'objets. Ils pourraient tous implémenter une interface vide. Ensuite, votre code pourrait simplement vérifier cette interface sans jamais avoir à connaître quoi que ce soit sur l'objet. Les classes abstraites sont utiles lorsque vous avez beaucoup de code partagé entre sous-classes, mais n'est pas significatif par lui-même. Vous pouvez déclarer la classe de base comme abstraite, implémenter toutes les fonctionnalités partagées et laisser le reste des fonctions vide. En déclarant cette classe de base comme abstraite, personne ne pourra jamais l'utiliser par elle-même.

Questions connexes