【发布时间】:2018-05-16 15:26:15
【问题描述】:
我有一个看起来像 this 的类。我也将其粘贴在下面以供参考:
<?php
trait T1
{
abstract protected function _doStuff();
}
trait T2
{
protected function _doStuff()
{
echo "Doing stuff in trait\n";
}
}
class C
{
use T1 {
_doStuff as _traitDoStuff;
}
use T2 {
_doStuff as _traitDoStuff;
}
protected function _doStuff()
{
echo "Doing stuff in class\n";
$this->_traitDoStuff();
}
}
这里发生了什么:
-
使用
T1::_doStuff(),别名为_traitDoStuff()。根据 PHP 文档,这不会重命名该方法,而只会添加一个别名。所以此时,_doStuff()和_traitDoStuff()都作为抽象保护方法存在。 -
使用
T2::_doStuff(),别名为_traitDoStuff()。根据 PHP 文档,由于优先级,两者都被T2的方法覆盖。所以此时,T1::_doStuff()不再存在。即使会,也会由T2::_doStuff()实现。 -
C实现_doStuff(),它调用_traitDoStuff()。至此,不管_doStuff()的哪个实现,显然都实现了这个方法,所以T1::_doStuff()定义的契约满足,或者不存在。
然而,当我运行它时,它给出了以下错误:
致命错误:C 类包含 1 个抽象方法,因此必须声明为抽象方法或实现其余方法 (C::_doStuff)
从 3v4l 可以看出,从 PHP 5.4 到 7.2 无处不在,这有点暗示这不是早期的 trait 错误。有人可以向我解释一下吗?
更新
显然,我只是忘记指定别名的方法,即T1::_doStuff as _traitDoStuff。
【问题讨论】:
-
不应该将 T1 实现为接口,而不是 trait 吗?
-
不确定这是什么意思,@bassxzero。
-
我知道接口是什么。我不知道你的句子是什么意思。我有一个特质。我不明白将特征实现为接口意味着什么。
-
C 类不应该实现 T1 接口。将你的抽象函数
do_stuff放入一个名为T1的接口中,然后让C 类实现T1 接口。