Dans ce chapitre, nous allons voir le principe de l'héritage en PHP, ainsi que la visibilité des propriétés et des méthodes. Ces notions permettent de mieux organiser le code lorsque plusieurs classes partagent un comportement commun, tout en ayant quelques différences.
L'idée est d'éviter de recopier la même logique dans plusieurs classes. Une classe peut reprendre le fonctionnement d'une autre, puis modifier uniquement les parties qui doivent changer.
Transformer une logique en objet
Avant de parler d'héritage, on peut commencer par déplacer une logique existante dans une classe. Une classe permet de regrouper les informations nécessaires et les méthodes qui travaillent avec ces informations.
Le constructeur reçoit ici une valeur nécessaire au fonctionnement de l'objet et la stocke dans une propriété. Cette propriété pourra ensuite être réutilisée par les autres méthodes de la classe.
L'intérêt est que l'objet garde les informations dont il a besoin. On n'a donc pas à repasser systématiquement les mêmes paramètres à chaque fonction.
Ajouter des méthodes d'instance
Une fois les données stockées dans l'objet, on peut ajouter des méthodes qui utilisent ces propriétés. Ces méthodes décrivent les actions possibles sur l'objet.
On peut ensuite utiliser l'objet sans se soucier de la logique interne :
Cette première étape montre l'intérêt des classes : on rassemble la logique liée à un concept au même endroit, avec une API plus claire à utiliser depuis le reste de l'application.
Le problème de la duplication
On peut parfois avoir besoin d'une classe très proche d'une autre, avec seulement une petite différence de comportement. Une première solution serait de recopier toute la classe, puis de modifier la méthode concernée.
Cette solution fonctionne, mais elle pose un problème : si la logique commune doit changer, il faudra la modifier à plusieurs endroits. C'est exactement le type de répétition que l'héritage permet d'éviter.
Hériter d'une classe
L'héritage permet de créer une classe qui reprend les propriétés et les méthodes d'une autre classe. Pour cela, on utilise le mot-clé extends.
La classe qui hérite récupère automatiquement le fonctionnement de la classe parente. Même si elle ne contient pas encore de code, elle peut utiliser les méthodes définies dans la classe dont elle hérite.
L'intérêt est de pouvoir créer une variante d'un comportement existant, sans recopier toute la logique.
Redéfinir une méthode
Une classe enfant peut modifier une méthode héritée. On parle alors de redéfinition de méthode. Il suffit de déclarer dans la classe enfant une méthode qui porte le même nom.
Le mot-clé parent permet d'appeler la méthode définie dans la classe parente. Cela évite de réécrire toute la logique si on veut simplement adapter le résultat.
On peut aussi ajouter de nouvelles méthodes dans la classe enfant. Elles seront disponibles uniquement sur cette classe et sur les classes qui en hériteraient ensuite.
L'héritage sert donc à exprimer qu'une classe fonctionne comme une autre, mais avec quelques différences ou fonctionnalités supplémentaires.
Comprendre la visibilité
Les mots-clés public, private et protected permettent de définir la visibilité d'une propriété ou d'une méthode. Cette visibilité indique depuis où l'élément peut être utilisé.
Avec public, l'élément est accessible depuis l'intérieur de la classe, mais aussi depuis l'extérieur.
Avec private, l'élément est accessible uniquement à l'intérieur de la classe qui le définit. Il ne peut pas être appelé depuis l'extérieur, ni utilisé directement dans une classe enfant.
Avec protected, l'élément reste inaccessible depuis l'extérieur, mais il peut être utilisé dans la classe courante et dans les classes enfants.
On peut résumer les visibilités comme ceci :
public: accessible depuis l'intérieur et l'extérieur de la classe.private: accessible uniquement dans la classe qui le définit.protected: accessible dans la classe qui le définit et dans ses classes enfants.
Pourquoi ne pas tout mettre en public ?
On pourrait être tenté de tout rendre public pour ne jamais avoir de problème d'accès. Mais la visibilité sert aussi à organiser le code et à rendre l'intention plus claire.
Quand une propriété ou une méthode est privée ou protégée, on comprend qu'elle fait partie du fonctionnement interne de la classe. À l'inverse, ce qui est public représente ce que l'on est censé utiliser depuis l'extérieur.
Un bon réflexe consiste à rendre les éléments privés par défaut, puis à ouvrir uniquement ce qui doit réellement être utilisé :
- si l'élément doit être appelé depuis l'extérieur, on le met en
public. - s'il ne sert qu'à la classe elle-même, on le garde en
private. - s'il doit aussi être accessible aux classes enfants, on le met en
protected.
Le constructeur, lui, reste public, car il doit pouvoir être appelé au moment de créer l'objet.
Ces règles de visibilité s'appliquent aussi aux méthodes et propriétés statiques. On peut donc avoir public static, private static ou protected static.
Constantes de classe
Une classe peut aussi définir des constantes. Elles ressemblent à des propriétés statiques, mais leur valeur ne change pas.
Contrairement aux propriétés statiques, une constante ne s'appelle pas avec un $.
Une classe enfant peut redéfinir une constante, mais il faut faire attention au mot-clé utilisé pour y accéder.
Si la classe parente utilise self::INCREMENT, self fera toujours référence à la classe dans laquelle la méthode est définie. Dans ce cas, la constante de la classe enfant ne sera pas utilisée.
Pour que PHP tienne compte de la classe réellement appelée, on peut utiliser static::INCREMENT. C'est ce qu'on appelle la résolution statique à la volée.
Avec static::, PHP regarde le contexte réel d'exécution et peut donc utiliser la constante redéfinie dans une classe enfant.
À retenir
L'héritage permet de créer une classe à partir d'une autre avec extends. La classe enfant récupère les propriétés et méthodes de la classe parente, puis peut redéfinir certaines méthodes ou ajouter son propre comportement.
La visibilité permet de mieux contrôler ce qui fait partie de l'API publique d'une classe et ce qui relève de son fonctionnement interne. public, private et protected ne servent pas seulement à éviter des erreurs : ils aident aussi à rendre le code plus lisible et mieux organisé.
Ressources
Pour aller plus loin, vous pouvez consulter la documentation officielle PHP sur l'héritage, la visibilité et la résolution statique à la volée.