我想知道为什么 PHP Trait (PHP 5.4) 不能实现接口(interface)。
从 user1460043 的答案更新 => ...不能要求使用它来实现特定接口(interface)的类
我知道这可能很明显,因为人们可能会认为,如果 Class A
正在使用实现 interface I
的 Trait T
code>,而不是 Class A
应该非直接地实现 interface I
(这是不正确的,因为 Class A
可以重命名 trait 方法)。
就我而言,我的特征是从使用该特征的类实现的接口(interface)调用方法。
特征实际上是接口(interface)某些方法的实现。 所以,我想在代码中“设计”每个想要使用我的特性的类都必须实现接口(interface)。这将允许 Trait 使用接口(interface)定义的类方法,并确保它们存在于类中。
最佳答案
真正简短的版本更简单,因为你不能。这不是 Traits 的工作原理。
当您在 PHP 中编写 use SomeTrait;
时,您(有效地)告诉编译器将代码从 Trait 复制并粘贴到正在使用它的类中。
因为 use SomeTrait;
在类里面,所以不能把 implements SomeInterface
添加到类中,因为那必须在类外。
"why aren't Traits types in PHP? "
因为它们不能被实例化。特质真的只是一个language construct (告诉编译器将特征代码复制并粘贴到此类中),而不是您的代码可以引用的对象或类型。
So, i want to "design" in the code that every class that want to use my trait have to implement the interface.
这可以通过使用抽象类来使用
特征然后从它扩展类来强制执行。
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。
或者你的逻辑错误。您的意思是要求实现接口(interface)的类具有某些功能,而不是如果它们具有某些功能就必须将自己声明为实现接口(interface)。
编辑
实际上你可以在 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 中实现接口(interface),并且仍然闻起来像一个糟糕的设计,因为在定义类需要履行的契约方面,接口(interface)比 trait 好得多。
关于php - 为什么 PHP Trait 不能实现接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14665978/