真正简短的版本更简单,因为你不能。这不是 Traits 的工作原理。
当您在 PHP 中编写 use SomeTrait; 时,您(有效地)告诉编译器将代码从 Trait 复制并粘贴到正在使用它的类中。
因为use SomeTrait;在类里面,它不能把implements SomeInterface添加到类中,因为那必须在类外。
“为什么 PHP 中没有 Traits 类型?”
因为它们不能被实例化。 Traits 实际上只是 language construct(告诉编译器将 trait 代码复制并粘贴到此类中),而不是您的代码可以引用的对象或类型。
所以,我想在代码中“设计”每个想要使用的类
我的 trait 必须实现接口。
这可以使用抽象类来强制执行use 特征,然后从它扩展类。
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();
但是 - 如果您确实需要强制使用 Trait 的任何类都具有特定的方法,我认为您可能在最初应该是抽象类的地方使用了 Trait。
或者你的逻辑错误。您的意思是要求实现接口的类具有某些功能,而不是如果它们具有某些功能就必须将自己声明为实现接口。
编辑
实际上你可以在 Traits 中定义抽象函数来强制一个类实现该方法。例如
trait LoggerTrait {
public function debug($message, array $context = array()) {
$this->log('debug', $message, $context);
}
abstract public function log($level, $message, array $context = array());
}
但是,这仍然不允许您在 trait 中实现接口,而且仍然闻起来像一个糟糕的设计,因为在定义类需要履行的契约方面,接口比 trait 好得多。