真正简短的版本更简单,因为你不能。这不是 Traits 的工作方式。
当您用use SomeTrait;
PHP 编写代码时,您(有效地)告诉编译器将代码从 Trait 复制并粘贴到正在使用它的类中。
因为在use SomeTrait;
类内,它不能添加implements SomeInterface
到类中,因为它必须在类外。
“为什么 PHP 中没有 Traits 类型?”
因为它们不能被实例化。特征实际上只是一种语言结构(告诉编译器将特征代码复制并粘贴到此类中),而不是代码可以引用的对象或类型。
所以,我想在代码中“设计”每个想要使用我的特性的类都必须实现接口。
这可以使用一个抽象类来强制执行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 的任何类都具有特定的方法,我认为您可能正在使用应该首先是抽象类的特征。
或者你的逻辑错误。您的意思是要求实现接口的类具有某些功能,而不是如果它们具有某些功能,则必须将自己声明为实现接口。
编辑
实际上,您可以在 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 好得多。