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 vous devez parfois 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 respecter.
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 dépend de l’implémentation de getEmail() par la classe. Cela crée un modèle puissant dans lequel le trait gère la logique commune tout en déléguant les détails spécifiques à la classe qui l’implémente.
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, ce qui rend votre code plus prévisible et plus facile à maintenir.
Défi
FacileConstruisons un système de tarification dans lequel différents types de produits calculent leur prix final différemment, tout en partageant une logique commune de remise grâce à un trait doté d’une méthode abstraite.
Vous organiserez votre code sur trois fichiers :
Discountable.php: créez un trait appeléDiscountablequi fournit les fonctionnalités de remise. Le trait doit comporter :- Une méthode abstraite
getBasePrice(): floatque les classes utilisant ce trait doivent implémenter - Une méthode
applyDiscount(int $percent)qui calcule et renvoie le prix après application du pourcentage de remise au prix de base - Une méthode
getFinalPrice(int $percent)qui renvoie une chaîne formatée :"Final price: $[discounted_price]"avec 2 décimales
- Une méthode abstraite
Product.php: créez une classeProductqui utilise le traitDiscountable. Incluez le fichier du trait. Utilisez la promotion du constructeur pour définir un$nameprivé (chaîne de caractères) et un$priceprivé (nombre à virgule flottante). Implémentez la méthode requisegetBasePrice()pour renvoyer 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 deProductet 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
- Le prix de base formaté comme
Ce modèle est puissant, car le trait Discountable peut être utilisé par n’importe quelle classe : produits, services, abonnements, à condition qu’ils implémentent getBasePrice(). Le trait fournit la logique de remise partagée, tandis que chaque classe définit l’origine de son prix de base.
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
?>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
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition des méthodesLe mot-clé finalClasses abstraitesRécapitulatif – Hiérarchie des employés7Encapsulation
Public, Protected, PrivateModificateurs d’accès en profondeurAccesseurs et mutateursDissimulation de l’informationPromotion des constructeurs (8.0)Récapitulatif – Système de fiches étudiant10Concepts avancés de la POO
Composition ou héritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibres (PHP 8.1)Approfondissement du clonage d’objetsGénérateurs et itérateurs13Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron Dépôt2Espaces de noms et chargement automatique
Introduction aux espaces de nomsLe mot-clé useNorme de chargement automatique PSR-4Autoloader de ComposerRécapitulatif - Projet organisé5Interfaces et contrats
Introduction aux interfacesImplémentation des interfacesImplémentation de plusieurs interfacesInterface ou classe abstraiteIndication de type avec les interfacesRécapitulatif - Calculateur de formes8Méthodes magiques
Introduction aux méthodes magiques__toString et __debugInfo__get, __set, __isset, __unset__call et __callStatic__clone et clonage d’objets__serialize et __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d’instance vs statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés en lecture seule (PHP 8.1)Récapitulatif - Gestionnaire de comptes bancaires6Polymorphisme
Révision de la redéfinition des méthodesPolymorphisme via les interfacesAnnotations de type et types unionLiaison statique tardiveRécapitulatif - Processeur de paiements9Traits
Introduction aux traitsUtilisation de plusieurs traitsRésolution des conflits entre traitsMéthodes abstraites dans les traitsTraits par rapport à l’héritage12Patrons de conception – Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur PHP en ligne