Cet article est une continuation de l’ancien article sur les traits
L’introduction des traits pose un nouveau problème concernant la surcharge des méthodes. Jusqu’à présent une méthode redéfinie dans une classe fille écrasait la méthode de la classe mère. Mais comment faire avec les traits. C’est le concept de précédence : les méthodes héritées sont surchargées par les méthodes injectées par un trait, elles-mêmes surchargées par les méthodes de la classe courante
<?php //Enter your code here, enjoy! class UneClasse { public function uneMethode() { echo __METHOD__; } public function uneAutreMethode() { echo __METHOD__; } public function uneDerniereMethode() { echo __METHOD__; } } trait UnTrait { public function uneAutreMethode () { echo __METHOD__; } public function uneDerniereMethode() { echo __METHOD__; } } class Precedence extends UneClasse { use UnTrait; public function uneDerniereMethode() { echo __METHOD__; } } $obj = new Precedence (); $obj->uneMethode(); // Affiche UneClasse::uneMethode $obj->uneAutreMethode(); // Affiche UnTrait::uneAutreMethode $obj->uneDerniereMethode(); // Affiche Precedence::uneDerniereMethode
- Visibilités et alias de méthodes
Lors de la déclaration d’un trait au sein d’une classe il est possible de modifier certaines informations comme la visibilité des méthodes qui y sont définies. Il est aussi possible de leur appliquer un alias. Ceci est possible grâce au mot-clé as.
Changement de la visibilité d’une méthode
<?php trait UnTrait { public function uneMethode () { echo 1; } private function uneAutreMethode() { echo 2; } } class UneClasse { use UnTrait { uneMethode as private; uneAutreMethode as public; } } $obj = new UneClasse (); //$obj->uneMethode(); // Affiche : Fatal error : Call to private methode $obj->uneAutreMethode(); // Affiche 2
- Déclaration de traits multiples
Comme vu précédemment, une classe peut utiliser plusieurs traits en les déclarant avec le mot-clé use et en les séparant par une virgule. Si deux d’entre eux tentent d’injecter une méthode du même nom. PHP lèvera une erreur de niveau E_FATAL si le conflit n’est pas résolu.
Pour résoudre ce conflit, il est possible de donner la priorité à une des deux méthodes (donc d’exclure l’autre) en utilisant le mot-clé insteadof.
Exemple de conflit
<?php trait trait1 { public function uneMethode() { echo 1; } } trait trait2 { public function uneMethode() { echo 2; } } class Test { use trai1, trait2; } // Affichage : Fatal error : ....
Exemple de priorisation
<?php trait trait1 { public function uneMethode() { echo 1; } public function uneAutreMethode() { echo 2; } } trait trait2 { public function uneMethode() { echo 'A'; } public function uneAutreMethode() { echo 'B'; } } class Test { use trait1, trait2 { trait1::uneMethode insteadof trait2; trait2::uneMethode as unAlias; trait2::uneAutreMethode insteadof trait1; } } $obj = new Test(); $obj->uneMethode();// Affiche 1 $obj->uneAutreMethode(); // Affiche B $obj->unAlias(); // Affiche A
Il faut bien comprendre que nous ne sommes pas ici dans un contexte d’héritage classique mais bien dans une composition horizontale. A ce titre, le trait a accès à toute la classe comme s’il en faisait partie intégrante. Une fois un trait est déclaré au sein d’une classe, il peut donc utiliser des attributs et des méthodes privées de la classe
Si vous aimez, merci de partager avec vos amis