Concept d'interface

Eléphanteau du PHP | 17 Messages

28 nov. 2009, 04:32

Bonjour, je suis entrain de lire un livre sur le SPL (standard PHP library) et je tombe sur le concept des interfaces pour PHP. J'ai déjà vu ce concept et j'y comprends absolument rien. A quoi sert l'implentation d'une interface pour une class ?
Quand je lis en anglais je ne comprends pas l'utilité imédiate et futur. De plus, je comprends pas très bien l'utilisation d'une class abstraite. Peut-être quelqu'un peut m'éclairer un peu. Par contre, je comprends très bien les bases de la programmation OOP.

Est-ce que c'est seulement pour nous rappeller d'implanter les méthodes inscrite dans l'interface. Ainsi, nous éviter d'oblier une méthode???


Merci

Cordialement
Andre
Better to fight for something than live for nothing.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

28 nov. 2009, 17:55

Une interface, c'est un peu comme une classe mère, mais dans lequel aucun code n'est demandé, juste le prototype des méthode.
Le prototype d'une méthode, c'est : le nom, la visibilité (private/protected/public), la liste des paramètres ainsi que leur type (signature).

Utiliser une interface plutôt qu'une classe mère permet de dire : tout classe qui implémente telle interface doit implémenter cette liste de méthode.
Ainsi, une fois que tu dis qu'une classe implémente une interface, tu peux, sans te poser de question, appeler sur une instance de cette classe toutes les méthodes que l'interface demande.
La grosse différence entre la classe mère et l'interface est que la classe mère, lorsqu'elle définit une méthode, elle contient du code dans chaque méthode. C'est donc qu'elle sait à l'avance comment va réagir la classe fille.
Alors que l'interface ne sais pas quel code est nécessaire, elle ne fait que lister les méthodes à implémenter, mais sans présager du code nécessaire.

Pour prendre un exemple plus illustré :
héritage simple
La classe "Vehicule" contient une méthode faitLePlein($nb_litre).
Les classes "Voiture" et "Moto" hérite de la classe "Vehicule"

Ici, il faut utiliser l'héritage, puisque l'action de faire le plein sera semblable entre les différentes implémentations, et il est donc possible de pré-définir ce que sera le code de cette méthode, ce qui permet de n'ajouter que le spécifique dans les classes filles.

interface
L'interface "EmailFactory" qui contient le prototype de la méthode "envoyerMail($from, $to, $subject, $body)"
Les classes "SwiftEmail" et "PHPEmail" implémentent l'interface "EmailFactory"

Ici, il faut utiliser l'interface, parce qu'il n'est pas possible de présager de comment on envoi un email avec Swift ou PHP, et il est probable que les différentes implémentations seront différentes.
Toutefois, si on vérifie qu'une classe implémente l'interface "EmailFactory", tu sais que tu peux appeler la méthode envoyerEmail() sans te poser de question.

Il existe aussi le cas de l'héritage abstrait, mais on sort un peu du sujet de base ;)

PS : ah bah, en relisant ton code, non, l'héritage abstrait, tu poses la question.

Donc, l'héritage, c'est de pouvoir réutiliser le contenu d'une classe, en y apportant des spécificités. on est OK ?
Si on reprend l'exemple des classe "Vehicule", "Voiture" et "Moto", si tu n'utilises pas de classe abstraite, rien ne t'empêche d'instancier la classe "Vehicule".
Or, comme ça n'as aucun sens d'implémenter un véhicule, qui n'est prévu que pour mutualiser le code entre les différents véhicule, il faut rendre cette classe abstraite. Ainsi, tu ne pourras plus l'implémenter directement.

Donc, pour résumer :
héritage simple : tu peux utiliser la classe mère, ou la classe fille, et le code peut être définie dans la mère (pour tout ce qui est générique) ou la fille (pour ce qui est spécifique à la fille)
héritage abstrait : tu peux placer du code dans la classe mère (pour tout ce qui est générique) ou la fille (pour ce qui est spécifique à la fille), mais tu ne peux pas utiliser directement la classe mère, il faut définir une classe fille
interface : l'interface ne peux être instanciée, elle ne contient aucun code, juste une liste de fonction à implémenter, et cela te permet de garantir que toute classe qui implémente l'interface contiendra les méthodes de l'interface, avec la même signature.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer