web-dev-qa-db-fra.com

Étendre les traits avec des classes en PHP?

Pourquoi nous ne sommes pas autorisés à étendre les traits avec des classes en PHP?

Par exemple:

Trait T { }

Class C use T {}
/* or */
Class C extends T {}

Existe-t-il un conflit potentiel pour une telle syntaxe? Je ne pense pas.

31
Meglio

Le manuel PHP déclare ainsi:

Traits est un mécanisme de réutilisation de code dans des langages à héritage unique tels que PHP. Un trait est destiné à réduire certaines limitations de l'héritage unique en permettant à un développeur de réutiliser librement des ensembles de méthodes dans plusieurs classes indépendantes vivant dans des hiérarchies de classes différentes. La sémantique de la combinaison des traits et des classes est définie d'une manière qui réduit la complexité et évite les problèmes typiques associés à l'héritage multiple et aux mixins.

Si vous cherchez à étendre un trait, il devrait probablement s'agir d'une classe. Si vous avez un ensemble de méthodes dans une classe que vous souhaitez utiliser dans d'autres, mais qu'il vous semble inapproprié d'étendre la classe (par exemple. class Animal extends Vehicle), puis en PHP 5.4 cela pourrait bien fonctionner comme un trait.

Pour répondre plus directement à la question, vous ne "prolongez" pas un trait, mais vous pouvez créer des traits qui eux-mêmes utilisent d'autres traits. Selon le manuel PHP:

trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World!';
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}

Vous pouvez considérer cela comme un moyen de conserver vos traits dans des groupes logiques et d'introduire une certaine modularité.

Edit: après avoir vu certains des commentaires, je pense qu'il vaut la peine de noter que l'utilisation d'un trait dans une classe de base signifie également que le trait est dans n'importe quelle classe qui l'étend, et les fonctions du trait ont priorité sur la classe de base ''. Le mettre dans la classe enfant rendrait simplement les fonctions du trait inaccessibles à la classe parent/base.

Parent > Trait > Child

http://php.net/manual/en/language.oop5.traits.php

36
mrlee

Vous pouvez étendre quelque peu les traits. Développant la réponse de mrlee, lorsque vous use un trait, vous pouvez renommer ses méthodes.

Disons par exemple que vous avez un trait "parent" qui a été défini par votre framework:

trait FrameworkTrait {
    public function keepMe() {
        // Framework's logic that you want to keep
    }

    public function replaceMe() {
        // Framework's logic that you need to overwrite
    }
}

Tirez simplement le trait parent, renommez sa méthode replaceMe en autre chose et définissez votre propre méthode replaceMe.

trait MyTrait {
    use FrameworkTrait {
        FrameworkTrait::replaceMe as frameworkReplaceMe;
    }

    public function replaceMe() {
        // You can even call the "parent" method if you'd like:
        $this->frameworkReplaceMe();

        // Your logic here
    }
}

Et puis dans votre classe:

class MyClass {
    use MyTrait;
}

Maintenant, les objets de cette classe peuvent faire ceci:

$obj = new MyClass();

$obj->keepMe();             // calls "parent" trait
$obj->replaceMe();          // calls "child" trait
$obj->frameworkReplaceMe(); // calls "parent" trait
19
andrewtweber

Seules les classes peuvent être prolongées. Les traits sont pas classes. Ils peuvent être utilisés/inclus par classes mais ne sont pas des classes elles-mêmes. Si vous pensez qu'un trait doit être étendu, il devrait probablement s'agir d'une classe, probablement abstraite, et non d'un trait.

6
John Conde