Nous avons vu précédemment que les classes abstraites étaient un bon moyen de forcer des implémentations dans les branches et les feuilles de l’arbre d’héritage et que c’était aussi un moyen d’interdire l’instanciation de classes que l’on juge trop « génériques » (on s’instancie pas un « être vivant », c’est une notion trop abstraite, on aimerait plutôt instancier Homme ou Baleine).
Une classe abstraite peut implémenter une (ou des) interfaces :
interface Reproduction { public function seReproduire(); } interface Alimentation { public function seNourrir(); }
EtreVivant est une classe abstraite donc rien ne l’oblige à implémenter l’intégralité des fonctions (publiques, toujours !) imposées par les interfaces Reproduction et Alimentation, ce qui serait évidemment le cas si elle était concrète. Comme dans la partie 1, elle délègue cette obligation à la première classe concrète qui va la dériver…
interface Reproduction { public function seReproduire(); } interface Alimentation { public function seNourrir(); } abstract class EtreVivant implements Reproduction, Alimentation {} class Baleine extends EtreVivant { public function seReproduire() { // décrivez ici de manière poétique // l'accouplement de ces majestueux animaux } public function seNourrir() { echo "Je mange du krill et du zooplancton", PHP_EOL; } }
Bien entendu, une classe abstraite peut prendre en charge une partie de l’implémentation des méthodes imposées par une interface et déléguer le reste à ses filles…
interface Propulsion { public function pedaler(); } interface Freinage { public function freiner(); } abstract class Velo implements Propulsion, Freinage { public function pedaler() { $this->mettrePiedsSurPedales(); $this->appuyerSurPedales(); } public function mettrePiedsSurPedales() { echo "Je mets les pieds sur les pédales", PHP_EOL; } public function appuyerSurPedales() { echo "J'appuie sur les pédales", PHP_EOL; } } class BMX extends Velo { public function freiner() { echo "Les patins appuient sur les roues", PHP_EOL; } } class VTTDernierCri extends Velo { public function freiner() { echo "Les plaquettes appuient sur les disques", PHP_EOL; } }
Dans notre cas, Velo, qui est abstraite, a pris en charge une partie des méthodes imposées par les interfaces(imposées…pas vraiment, puisqu’elle est abstraite); elle a choisi d’implémenter pedaler, qui provient de l’interface Propulsion. En effet, qu’on conduise un vélo de course, de descente, un BMX ou le tricycle d’un enfant, on n’y coupe pas : il faut pédaler, et toujours de la même manière !
Par contre le freinage peut être délégué aux filles car son implémentation va dépendre directement de la classe concrète…En effet un vieux vélo ne freine pas forcément de la même manière qu’un nouveau (la plupart des nouveaux vélos ont des freins à disques, les anciens – le mien 🙁 – ont encore des freins à étrier avec des patins…).