Héritage en PHP OOP
Apprenez l'héritage en PHP OOP : syntaxe extends, redéfinition de méthodes, mot-clé parent et final avec des exemples complets.
L'héritage permet à une classe de réutiliser les propriétés et les méthodes d'une autre, afin de modéliser des relations « est-un » (une Car est un Vehicle) sans dupliquer le code. En PHP, il est mis en œuvre avec le mot-clé extends. Ce chapitre couvre la syntaxe, le fonctionnement de la redéfinition de méthodes et du mot-clé parent, l'héritage des constructeurs, le rôle de la visibilité et du mot-clé final, ainsi qu'un exemple complet et exécutable sur lequel vous pourrez expérimenter.
Si vous débutez avec les classes, commencez par les classes et objets PHP, puis revenez ici.
Qu'est-ce que l'héritage ?
L'héritage est la capacité de définir une nouvelle classe (la classe enfant, sous-classe ou classe dérivée) à partir d'une classe existante (la classe parente, superclasse ou classe de base). L'enfant hérite automatiquement des membres public et protected du parent et peut :
- les réutiliser tels quels,
- les redéfinir avec sa propre implémentation, ou
- ajouter de nouvelles propriétés et méthodes.
PHP ne supporte que l'héritage simple : une classe ne peut étendre qu'un seul parent. Vous pouvez cependant construire une chaîne — Hatchback extends Car extends Vehicle — et une classe peut également implémenter plusieurs interfaces lorsque vous avez besoin de comportements provenant de plusieurs sources.
Avantages de l'héritage
- Réutilisabilité — la logique partagée se trouve dans le parent, vous ne l'écrivez donc qu'une seule fois.
- Maintenabilité — une correction dans le parent se propage à toutes les sous-classes ; moins de duplication signifie moins d'endroits où les bugs peuvent se cacher.
- Polymorphisme — du code qui attend un
Vehiclefonctionne avec n'importe quelle sous-classe, vous pouvez donc substituer les implémentations librement. - Modélisation claire — la hiérarchie de classes documente les relations « est-un » dans votre domaine.
Syntaxe de l'héritage en PHP OOP
Pour créer une sous-classe, écrivez extends suivi du nom de la classe parente :
class ChildClass extends ParentClass {
// child-specific properties and methods
}ChildClass possède désormais tous les membres public et protected de ParentClass. Notez que les membres private du parent ne sont pas accessibles depuis l'enfant — utilisez protected si vous souhaitez que les sous-classes puissent accéder à un membre tout en le gardant invisible depuis l'extérieur. Consultez les modificateurs d'accès PHP pour les règles de visibilité complètes.
Redéfinir les méthodes du parent
Une sous-classe redéfinit une méthode parente en déclarant une méthode avec le même nom. La version de l'enfant remplace celle du parent pour les objets de cette sous-classe :
class ParentClass {
public function displayMessage() {
echo "Hello from ParentClass";
}
}
class ChildClass extends ParentClass {
public function displayMessage() {
echo "Hello from ChildClass";
}
}Appeler la méthode parente avec parent::
Redéfinir ne signifie pas forcément remplacer — vous souhaitez souvent étendre le comportement du parent. Utilisez parent:: pour appeler d'abord la version du parent, puis y ajouter quelque chose :
class ChildClass extends ParentClass {
public function displayMessage() {
parent::displayMessage(); // runs the parent's logic
echo " — and hello from ChildClass";
}
}Ajouter l'attribut #[\Override] (PHP 8.3+) au-dessus d'une méthode indique à PHP de générer une erreur si elle ne redéfinit pas réellement une méthode parente — un moyen simple de détecter les fautes de frappe dans les noms de méthodes.
Héritage et extension des constructeurs
Si une classe enfant ne définit pas son propre constructeur, le constructeur parent est hérité et s'exécute automatiquement. Si l'enfant définit le sien, le constructeur parent n'est pas appelé automatiquement — vous devez l'appeler explicitement avec parent::__construct(...) :
class Vehicle {
public function __construct(public string $make) {}
}
class Car extends Vehicle {
public function __construct(string $make, public string $fuelType) {
parent::__construct($make); // initialise the inherited part
}
}Pour en savoir plus sur les constructeurs, consultez le constructeur PHP.
Empêcher la redéfinition avec final
Marquez une méthode final pour empêcher les sous-classes de la redéfinir, ou marquez toute une classe final pour empêcher qu'elle soit étendue :
class PaymentBase {
final public function transactionId(): string {
return 'TX-' . uniqid();
}
}C'est utile pour la logique qui doit se comporter de manière identique partout. Consultez le mot-clé final en PHP pour plus de détails. Lorsque le parent doit définir la signature d'une méthode mais forcer chaque enfant à en fournir le corps, utilisez plutôt une classe abstraite.
Exemple d'héritage en PHP OOP
Voici un programme complet et exécutable. Une classe de base Vehicle contient les données communes, et une sous-classe Car ajoute une propriété fuelType et étend displayDetails() via parent:: :
<?php
class Vehicle
{
public function __construct(
protected string $make,
protected string $model,
protected int $year
) {}
public function displayDetails(): void
{
echo "Make: {$this->make}\n";
echo "Model: {$this->model}\n";
echo "Year: {$this->year}\n";
}
}
class Car extends Vehicle
{
public function __construct(
string $make,
string $model,
int $year,
protected string $fuelType
) {
parent::__construct($make, $model, $year);
}
public function displayDetails(): void
{
parent::displayDetails(); // reuse the parent's output
echo "Fuel Type: {$this->fuelType}\n"; // then add our own
}
}
$car = new Car('Toyota', 'Corolla', 2023, 'Hybrid');
$car->displayDetails();Résultat :
Make: Toyota
Model: Corolla
Year: 2023
Fuel Type: HybridCar hérite de make, model et year (déclarés protected, afin que la sous-classe puisse les utiliser), réutilise le displayDetails() du parent via parent::, et ajoute sa propre ligne fuelType.
Pièges courants
privaten'est pas hérité. Une propriétéprivatedu parent est invisible pour l'enfant. Utilisezprotectedsi les sous-classes en ont besoin.- Les constructeurs ne sont pas chaînés automatiquement lorsque l'enfant définit le sien — appelez toujours
parent::__construct()vous-même. - PHP ne supporte pas l'héritage multiple. Une classe étend un seul parent ; utilisez des interfaces ou des traits pour partager des comportements depuis plusieurs sources.
- La redéfinition ignore silencieusement les fautes de frappe avant PHP 8.3 — un nom de méthode mal orthographié crée simplement une nouvelle méthode au lieu de redéfinir l'existante. Ajoutez
#[\Override]pour plus de sécurité.
Conclusion
L'héritage permet à une sous-classe de réutiliser, redéfinir et étendre les membres d'une classe parente via le mot-clé extends, parent:: donnant accès à l'implémentation originale. Combiné avec les modificateurs de visibilité, les constructeurs et final, il constitue le fondement de la réutilisation du code et du polymorphisme en PHP OOP. Explorez ensuite les classes abstraites et les interfaces pour concevoir des hiérarchies de classes plus propres.