真正简短的版本更简单,因为你不能。这不是特质的工作方式。
当你用PHP编写时,你(有效地)告诉编译器将代码从Trait复制并粘贴到使用它的类中。use SomeTrait;
因为 位于类内部,所以它不能添加到类中,因为它必须在类外部。use SomeTrait;
implements SomeInterface
“为什么PHP中的Traits不是类型?
因为它们无法实例化。Traits 实际上只是一种语言构造(告诉编译器将 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();
但是 - 如果你确实需要强制任何使用Tratraits的类都有一个特定的方法,我认为你可能正在使用你本来应该是抽象类的特征。
或者说你的逻辑是错误的。你打算要求实现接口的类具有某些函数,而不是要求如果它们具有某些函数,它们必须将自己声明为实现接口。
编辑
实际上,您可以在 Traits 中定义抽象函数,以强制类实现该方法。例如:
trait LoggerTrait {
public function debug($message, array $context = array()) {
$this->log('debug', $message, $context);
}
abstract public function log($level, $message, array $context = array());
}
然而,这仍然不允许你在特质中实现接口,并且仍然闻起来像一个糟糕的设计,因为在定义类需要履行的契约时,接口比特质要好得多。