Retour sur la redéfinition de méthode
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 33 sur 91.
Vous avez déjà découvert la redéfinition de méthode dans le chapitre sur l'héritage. Explorons maintenant comment cela se connecte au polymorphisme - l'un des concepts les plus puissants de la programmation orientée objet.
Le polymorphisme signifie « plusieurs formes ». Lorsque vous redéfinissez une méthode dans une classe enfant, vous donnez à cette méthode une forme différente tout en conservant le même nom. La magie opère lorsque vous travaillez avec des objets via leur type parent :
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()) . "\n";
echo makeAnimalSpeak(new Cat());
Sortie :
Woof!
Meow!La fonction makeAnimalSpeak() accepte n'importe quel Animal. Elle ne sait pas et ne se soucie pas de savoir si elle reçoit un Dog ou un Cat. PHP appelle automatiquement la méthode surchargée correcte en fonction du type d'objet réel au moment de l'exécution.
Voici le polymorphisme en action.
Cette approche vous permet d'écrire un code flexible qui fonctionne avec une famille d'objets apparentés sans connaître leurs types spécifiques. Vous pouvez ajouter de nouvelles classes d'animaux plus tard, et la fonction fonctionnera avec elles automatiquement.
Point clé : La redéfinition de méthode permet le polymorphisme en permettant à différentes classes de répondre différemment au même appel de méthode, déterminé au moment de l'exécution par le type réel de l'objet.
Défi
FacileConstruisons un système d'instruments de musique qui démontre le polymorphisme par la redéfinition de méthodes (method overriding). Vous allez créer une classe de base Instrument et deux classes enfants qui produisent chacune leur propre son unique — puis utiliser une seule fonction pour jouer n'importe quel instrument de manière polymorphe.
Vous organiserez votre code sur quatre fichiers :
Instrument.php— Créez une classeInstrumentavec une propriété protégée$namedéfinie via le constructeur. Ajoutez une méthodeplay()qui retourne"[name] makes a sound". Cela sert de comportement de base que les classes enfants vont redéfinir.Guitar.php— Créez une classeGuitarqui étendInstrument. Incluez le fichier parent. Le constructeur accepte le nom et le passe au constructeur parent. Redéfinissez la méthodeplay()pour qu'elle retourne"[name] strums a chord".Drum.php— Créez une classeDrumqui étendInstrument. Incluez le fichier parent. Le constructeur accepte le nom et le passe au constructeur parent. Redéfinissez la méthodeplay()pour qu'elle retourne"[name] beats a rhythm".main.php— Incluez les fichiers Guitar et Drum. Créez une fonction nomméeperformWithqui accepte un paramètreInstrument(avec un typage forcé / type-hint) et retourne le résultat de l'appel àplay()sur celui-ci. Cette fonction démontre le polymorphisme — elle fonctionne avec n'importe quel type d'instrument grâce au type-hint de la classe parente.
Vous recevrez deux entrées : un nom pour la guitare et un nom pour le tambour. Créez une Guitar et un Drum avec ces noms. Passez chacun d'eux à votre fonction performWith() et affichez les résultats — la guitare en premier, puis le tambour, chacun sur sa propre ligne.
Remarquez comment performWith() accepte n'importe quel Instrument, pourtant PHP appelle automatiquement la bonne méthode play() redéfinie en fonction du type réel de l'objet au moment de l'exécution. C'est le polymorphisme en action !
Aide-mémoire
Le polymorphisme signifie "plusieurs formes" et permet de traiter des objets de différentes classes via leur type parent tout en conservant leur comportement spécifique.
Lorsque vous redéfinissez une méthode dans des classes enfants, PHP appelle automatiquement la version correcte en fonction du type d'objet réel au moment de l'exécution :
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()); // Woof!
echo makeAnimalSpeak(new Cat()); // Meow!
La fonction makeAnimalSpeak() accepte n'importe quel type Animal grâce à l'indication de type de son paramètre. Elle n'a pas besoin de connaître la classe spécifique - PHP détermine quelle méthode redéfinie appeler au moment de l'exécution en fonction du type d'objet réel.
Cela permet d'écrire un code flexible qui fonctionne avec une famille d'objets apparentés sans connaître leurs types spécifiques. De nouvelles classes enfants peuvent être ajoutées ultérieurement et fonctionneront automatiquement avec les fonctions existantes.
Essayez vous-même
<?php
// Inclure les fichiers d'instruments
require_once 'Guitar.php';
require_once 'Drum.php';
// Lire l'entrée
$guitarName = trim(fgets(STDIN));
$drumName = trim(fgets(STDIN));
// TODO: Créer une fonction appelée performWith qui :
// - Accepte un paramètre Instrument (utiliser l'indication de type : Instrument $instrument)
// - Retourne le résultat de l'appel de play() sur l'instrument
// TODO: Créer une Guitar avec $guitarName et un Drum avec $drumName
// TODO: Passer chacun à performWith() et afficher les résultats (guitare d'abord, puis batterie)
?>Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Les bases de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition de méthodeLe mot-clé finalClasses abstraitesRécapitulatif - Hiérarchie des employés7Encapsulation
Public, Protégé, PrivéModificateurs d'accès en détailGetters et SettersMasquage d'informationPromotion de constructeur (8.0)Récapitulatif - Système de gestion d'étudiants10Concepts avancés de la POO
Composition vs HéritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibers (PHP 8.1)Clonage d'objets : analyse approfondieGénérateurs et Itérateurs13Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository2Espaces de noms et Autoloading
Introduction aux espaces de nomsLe mot-clé useStandard d'Autoloading PSR-4L'Autoloader ComposerRécapitulatif - Projet organisé5Interfaces et Contrats
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesInterface vs Classe AbstraiteType Hinting avec les InterfacesRécapitulatif - Calculateur de Formes8Méthodes magiques
Introduction aux méthodes magiques__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Clonage d'objets__serialize & __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d'instance vs Propriétés statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés readonly (PHP 8.1)Récapitulatif - Gestionnaire de compte bancaire6Polymorphisme
Retour sur la redéfinition de méthodePolymorphisme via les interfacesType Hinting et Types d'unionLiaison statique tardiveRécapitulatif - Processeur de paiement9Traits
Introduction aux TraitsUtilisation de plusieurs TraitsRésolution des conflits de TraitsMéthodes abstraites dans les TraitsTraits vs Héritage12Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie