La version vraiment courte est plus simple parce que vous ne pouvez pas. Ce n'est pas comme ça que les traits fonctionnent.
Quand vous écrivez use SomeTrait;
en PHP, vous demandez (en fait) au compilateur de copier et coller le code du Trait dans la classe où il est utilisé.
Parce que le use SomeTrait;
se trouve à l'intérieur de la classe, il ne peut pas ajouter l'option implements SomeInterface
à la classe, parce que ça doit être en dehors de la classe.
"pourquoi les types Traits ne sont-ils pas en PHP ? "
Parce qu'ils ne peuvent pas être instanciés. Les traits sont vraiment juste un construction du langage (indiquant au compilateur de copier et coller le code du trait dans cette classe) par opposition à un objet ou un type qui peut être référencé par votre code.
Donc, je veux "concevoir" dans le code que chaque classe qui veut utiliser mon trait doivent implémenter l'interface.
Cela peut être mis en œuvre en utilisant une classe abstraite pour use
le trait et ensuite étendre les classes à partir de celui-ci.
interface SomeInterface{
public function someInterfaceFunction();
}
trait SomeTrait {
function sayHello(){
echo "Hello my secret is ".static::$secret;
}
}
abstract class AbstractClass implements SomeInterface{
use SomeTrait;
}
class TestClass extends AbstractClass {
static public $secret = 12345;
//function someInterfaceFunction(){
//Trying to instantiate this class without this function uncommented will throw an error
//Fatal error: Class TestClass contains 1 abstract method and must therefore be
//declared abstract or implement the remaining methods (SomeInterface::doSomething)
//}
}
$test = new TestClass();
$test->sayHello();
Cependant, si vous avez besoin d'imposer que toute classe qui utilise un Trait possède une méthode particulière, je pense que vous utilisez des Traits là où vous auriez dû utiliser des classes abstraites en premier lieu.
Ou que votre logique est à l'envers. Vous êtes censé exiger que les classes qui implémentent des interfaces aient certaines fonctions, et non pas que si elles ont certaines fonctions, elles doivent se déclarer comme implémentant une interface.
Modifier
En fait, vous pouvez définir des fonctions abstraites à l'intérieur des Traits pour forcer une classe à implémenter la méthode, par exemple
trait LoggerTrait {
public function debug($message, array $context = array()) {
$this->log('debug', $message, $context);
}
abstract public function log($level, $message, array $context = array());
}
Cependant, cela ne vous permet toujours pas d'implémenter l'interface dans le trait, et cela sent toujours la mauvaise conception, car les interfaces sont bien meilleures que les traits pour définir un contrat qu'une classe doit remplir.