我有PHP特征的问题。我想在类和类中使用的特征中使用特征。
例:
trait Loggable {
protected function log(msg) {
echo msg;
}
}
trait SomeOtherTrait {
use Loggable;
}
class MyClass {
use SomeOtherTrait, Loggable;
}
但是这会导致碰撞,因为Loggable在类中使用了两次(一次在类中,一次通过另一个特性),但我不明白这个问题,因为封装功能是特性的全部,对吧?所以我只想在每个包含Loggable特征的地方使用log方法...
所以问题是:为什么我会发生碰撞?两者(特征和类)都指向相同的特征和方法,因此它不应该是冲突。
SomeOtherTrait使用特征Loggable,因此您可以访问Loggable的所有受保护和公共成员,这同样适用于使用SomeOtherTrait的所有类。在这里,您可以访问Loggable和SomeOtherTrait的所有公共和受保护成员。
trait Loggable {
protected function log($msg) {
echo $msg;
}
}
trait SomeOtherTrait {
use Loggable;
}
class MyClass {
use SomeOtherTrait;
public function test()
{
$this->log("test");
}
}
$myClass = new MyClass();
$myClass->test();
使用特征将其所有方法和属性复制到类中。它与扩展不同。所以实际上你试图将相同的log
方法两次复制到MyClass
。
如果您确实需要/想要使用这两种特征,则需要按照the manual中的描述解决此冲突。例如:
class MyClass {
use SomeOtherTrait, Loggable {
SomeOtherTrait::log insteadof Loggable;
}
}
要么:
class MyClass {
use SomeOtherTrait, Loggable {
Loggable::log as originalLog;
SomeOtherTrait::log as overriddenLog;
}
public function test() {
$this->originalLog('Logged with Loggable');
$this->overriddenLog('Logged with SomeOtherTrait');
}
}