L'héritage comme l'encapsulation est un des principes fondamentaux de le programmation objet.
Un héritage est défini par la relation "est un" ou "est une" : une voiture est un véhicule, une
guitare est un instrument de musique, PHP est un langage informatique.
Cette relation n'est pas symétrique : tous les véhicules ne sont pas des voitures, tous les
instruments de musique ne sont pas des guitares et tous les programmes ne sont pas écrits en PHP.
L'héritage permet de réutiliser du code et de définir de nouvelles classes à partir de classes existantes.
On va donc utiliser le code déjà écrit et testé d'une première classe (la classe de base) et ajouter de nouvelles fonctionnalités dans une seconde classe (la classe dérivée).
La classe de base est également appelée classe mère ou encore super-classe. Les 3 termes sont synonymes.
La classe dérivée est également appelée classe fille ou encore sous-classe. Les 3 termes sont synonymes.
La relation entre la classe mére et la classe fille se fait avec le mot-clé extends
placé entre le nom des classes dans la définition de la classe fille.
On dit que La classe fille hérite de la classe mére. Elle bénéficie de tous les
attributs et de toutes les méthodes de la classe mére, si ils/elles ne sont pas private.
Pour qu'une classe fille puisse atteindre les attributs de sa classe mère, les attributs dans la
classe mère doivent être protected ou public (à éviter).
Pour qu'une classe fille puisse invoquer les méthodes de sa classe mère, les méthodes dans la
classe mère doivent être public ou protected.
|
Dans l'exemple suivant, nous allons étendre la classe Guitare pour qu'on puisse aussi gérer
des guitares électriques. Par rapport aux guitares de notre classe Guitare, une guitare
électrique a deux attributs supplémentaires : |
|
Le constructeur de la classe mère n'est pas appelé automatiquement quand on
instancie la classe fille. Si nécessaire il doit être appelé explicitement dans le constructeur
de la classe fille. On utilise alors l'opérateur de résolution de portée :: précédé
du mot-cle parent. On a fait la même chose dans l'exemple précédent pour faire
référence dans la classe fille à la constante SON_E de la classe mère.
L'héritage multiple n'est pas possible : une classe fille ne peut pas avoir plusieurs classes
méres.
Une classe mère peut quant à elle avoir plusieurs classe filles.
L'héritage multi-niveaux est possible : une classe fille peut avoir une classe mère, une classe
grand-mère, une classe arrière grand-mére, etc.
L'ajout de fonctionnalités dans la classe fille se fait en y ajoutant des nouvelles caractéristiques (ie des nouveaux attributs) et des nouvelles actions (ie des nouvelles méthodes. La classe fille étend ainsi les capacités de la classe mére. On dit également qu'une classe fille est une spécialisation de la classe mére : elle "travaille" sur un domaine plus pointu que la classe mére.
Dans l'exemple précédent on a ajouté 2 nouveaux attributs à la classe mére. Il suffit de les définir dans la classe fille comme n'importe quel autre attribut. Remarque : une classe mére n'a pas accès aux nouveaux attributs définis dans sa classe fille, et ce, quelque soit la visibilité de ces attributs.
Pour ajouter de nouvelle méthodes à la classe fille, il suffit de les définir comme n'importe quelle autre méthode. Remarque : une classe mére n'a pas accès aux nouvelles méthodes définies dans sa classe fille, et ce, quelque soit la visibilité de ces attributs.
A titre d'exemple, nous allons ajouter une nouvelle méthode dans la classe fille
GuitareElectrique. Cette méthode s'appelle getMedias() et donnera le code HTML pour
afficher une photo de la guitare et jouer un extrait sonore.
Le nom des fichiers est fait par transformation de l'attribut modele auquel on
ajoute l'extension .jpg pour les images et .mp3 pour l'audio. Les fichiers images sont le
répertoire visuel et les fichiers audio dans le répertoire audio.
Le code de la méthode est le suivant :
public function getMedias() {
$fichier = str_replace(' ', '_', $this->modele);
$fichier = strtolower($fichier);
return "<div><img src=visuels/$fichier.jpg>
<audio src=audio/$fichier.mp3 controls
style='width: 100px'></audio></div>";
}