Menu
Coddy logo textTech

Méthodes abstraites dans les Traits

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 54 sur 91.

Les traits peuvent fournir des méthodes prêtes à l'emploi, mais parfois vous avez besoin que la classe utilisant le trait implémente une fonctionnalité spécifique. C'est là que les méthodes abstraites dans les traits deviennent utiles - elles définissent un contrat que la classe utilisatrice doit remplir.

Lorsqu'un trait déclare une méthode abstraite, toute classe utilisant ce trait doit l'implémenter :

<?php
trait Notifiable {
    abstract public function getEmail(): string;
    
    public function sendNotification(string $message): void {
        echo "Sending to " . $this->getEmail() . ": $message";
    }
}

class User {
    use Notifiable;
    
    public function __construct(private string $email) {}
    
    public function getEmail(): string {
        return $this->email;
    }
}

$user = new User("john@example.com");
$user->sendNotification("Welcome!");

Sortie :

Sending to john@example.com: Welcome!

Le trait fournit la méthode sendNotification() mais s'appuie sur getEmail() pour être implémentée par la classe. Cela crée un modèle puissant où le trait gère la logique commune tout en déléguant les détails spécifiques à la classe à la classe d'implémentation.

Si une classe utilise le trait sans implémenter la méthode abstraite, PHP génère une erreur fatale. Cela garantit que les traits peuvent dépendre en toute sécurité de l'existence de certaines méthodes, rendant votre code plus prévisible et facile à maintenir.

challenge icon

Défi

Facile

Construisons un système de tarification où différents types de produits calculent leurs prix finaux différemment, mais partagent tous une logique de remise commune via un trait avec une méthode abstraite.

Vous organiserez votre code sur trois fichiers :

  • Discountable.php — Créez un trait appelé Discountable qui fournit une fonctionnalité de remise. Le trait doit avoir :
    • Une méthode abstraite getBasePrice(): float que les classes utilisant ce trait doivent implémenter
    • Une méthode applyDiscount(int $percent) qui calcule et retourne le prix après avoir appliqué le pourcentage de remise au prix de base
    • Une méthode getFinalPrice(int $percent) qui retourne une chaîne formatée : "Final price: $[discounted_price]" avec 2 décimales
    Le trait gère tous les calculs de remise, mais s'appuie sur chaque classe pour lui indiquer quel est le prix de base.
  • Product.php — Créez une classe Product qui utilise le trait Discountable. Incluez le fichier du trait. Utilisez la promotion de constructeur pour définir un $name privé (string) et un $price privé (float). Implémentez la méthode getBasePrice() requise pour retourner le prix du produit.
  • main.php — Incluez le fichier Product. Vous recevrez trois entrées : un nom de produit, un prix et un pourcentage de remise. Créez une instance de Product et affichez deux lignes :
    • Le prix de base formaté comme "Base: $[price]" avec 2 décimales
    • Le résultat de l'appel à getFinalPrice() avec le pourcentage de remise

Ce modèle est puissant car le trait Discountable peut être utilisé par n'importe quelle classe — produits, services, abonnements — tant qu'elles implémentent getBasePrice(). Le trait fournit la logique de remise partagée tandis que chaque classe définit d'où provient son prix de base.

Aide-mémoire

Les traits peuvent déclarer des méthodes abstraites qui doivent être implémentées par toute classe utilisant le trait :

<?php
trait Notifiable {
    abstract public function getEmail(): string;
    
    public function sendNotification(string $message): void {
        echo "Sending to " . $this->getEmail() . ": $message";
    }
}

class User {
    use Notifiable;
    
    public function __construct(private string $email) {}
    
    public function getEmail(): string {
        return $this->email;
    }
}

Le trait fournit des méthodes prêtes à l'emploi tout en exigeant que la classe implémente une fonctionnalité spécifique. Si une classe utilise le trait sans implémenter la méthode abstraite, PHP génère une erreur fatale.

Ce modèle permet aux traits de gérer la logique commune tout en déléguant les détails spécifiques à la classe implémentée.

Essayez vous-même

<?php

require_once 'Product.php';

// Lire les entrées
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$discountPercent = intval(trim(fgets(STDIN)));

// TODO: Créer une instance de Product avec le nom et le prix

// TODO: Afficher le prix de base formaté comme "Base: $[price]" avec 2 décimales

// TODO: Afficher le résultat de l'appel à getFinalPrice() avec le pourcentage de remise

?>
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