Menu
Coddy logo textTech

Traits par rapport à l’héritage

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 55 sur 91.

Maintenant que tu comprends le fonctionnement des traits, clarifions quand utiliser les traits plutôt que l’héritage. Les deux permettent de réutiliser du code, mais ils répondent à des objectifs différents et possèdent des caractéristiques distinctes.

L’héritage établit une relation « est-un ». Une classe Dog qui étend Animal signifie qu’un chien est un animal. La classe enfant hérite de l’identité de la classe parente et peut être utilisée partout où le type parent est attendu.

Les traits fournissent une capacité « possède-un ». Lorsqu’une classe utilise le trait Loggable, elle possède une fonctionnalité de journalisation — mais elle ne devient pas un enregistreur. Les traits ajoutent un comportement sans modifier ce qu’est fondamentalement la classe.

<?php
// Héritage : Dog EST un Animal
class Animal {
    public function breathe(): void {
        echo "Breathing";
    }
}

class Dog extends Animal {
    public function bark(): void {
        echo "Woof!";
    }
}

// Trait : Dog A une capacité de journalisation
trait Loggable {
    public function log(string $msg): void {
        echo "Log: $msg";
    }
}

class Cat extends Animal {
    use Loggable;
}

Différences clés à retenir :

AspectHéritageTraits
Relationest-unpossède une capacité
LimiteUn seul parentPlusieurs traits autorisés
Vérification de typeFonctionne avec instanceofAucune identité de type
Idéal pourLes relations hiérarchiquesLes comportements partagés entre des classes sans lien

Utilisez l’héritage lorsque les classes partagent une identité commune. Utilisez les traits lorsque des classes sans lien ont besoin de la même fonctionnalité sans faire partie du même arbre généalogique.

challenge icon

Défi

Facile

Construisons un système de véhicules qui montre quand utiliser l’héritage plutôt que les traits. Vous allez créer une hiérarchie de véhicules qui partagent une identité commune grâce à l’héritage, tout en ajoutant des fonctionnalités transversales grâce aux traits.

Vous organiserez votre code sur quatre fichiers :

  • Trackable.php : créez un trait appelé Trackable qui fournit une fonctionnalité de suivi GPS. Le trait doit avoir :
    • Une propriété privée $location (chaîne de caractères)
    • Une méthode setLocation(string $location) qui stocke la position actuelle
    • Une méthode getLocation() qui renvoie "Location: [location]"
    Ce trait représente une fonctionnalité "has-a" : n’importe quel véhicule peut disposer du suivi, mais le fait de disposer du suivi ne transforme pas quelque chose en véhicule.
  • Vehicle.php : créez une classe de base Vehicle qui établit la relation "is-a". Incluez le fichier du trait. Utilisez la promotion du constructeur pour définir une propriété protégée $brand. Ajoutez une méthode describe() qui renvoie "Vehicle: [brand]". Cette classe doit utiliser le trait Trackable, puisque tous les véhicules de notre flotte disposeront du GPS.
  • Car.php : créez une classe Car qui étend Vehicle. Incluez le fichier Vehicle. Utilisez la promotion du constructeur pour accepter la marque et une propriété privée $doors (entier). Appelez le constructeur parent avec la marque. Remplacez la méthode describe() pour qu’elle renvoie "Car: [brand] with [doors] doors".
  • main.php : incluez le fichier Car. Vous recevrez trois entrées : un nom de marque, un nombre de portes et une chaîne représentant une position. Créez une instance de Car, définissez sa position, puis affichez deux lignes :
    • Le résultat de l’appel à describe()
    • Le résultat de l’appel à getLocation()

Remarquez comment l’héritage et les traits fonctionnent ici ensemble : Car is a Vehicle (l’héritage établit l’identité), tandis que Vehicle has une fonctionnalité de suivi (le trait ajoute un comportement). Vous pourriez utiliser instanceof Vehicle pour vérifier si quelque chose est un véhicule, mais il n’existe aucun type "Trackable" contre lequel effectuer la vérification : c’est la différence essentielle entre ces deux approches.

Essayez vous-même

<?php
// Fichier principal - créer et tester l'instance Car

// TODO: Inclure le fichier Car.php

// Lire les entrées
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));

// TODO: Créer une instance Car avec brand et doors

// TODO: Définir l'emplacement de la voiture

// TODO: Afficher le résultat de describe()

// TODO: Afficher le résultat de getLocation()
?>
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur PHP en ligne