我使用PHP 7.1.0。
假设我们有一个特征,我们在一个类中使用它并重命名导入的方法:
trait T
{
public function A() {
echo ".";
}
}
class C
{
use T {
A as B;
}
}
$c = new C();
$c->B();
$c->A(); // Why does it work?
为什么PHP仍然允许我使用旧的方法名称(在这种情况下为A
)?
这真的很痛苦,因为在更复杂的示例中,您不能依赖于方法重命名 - 因此您可能会意外地收到“不兼容的声明”错误:
class BaseSrc
{
}
trait BaseTrait
{
public function init(BaseSrc $baseSrc)
{
echo "Init Base";
}
}
class Base
{
use BaseTrait {
BaseTrait::init as initBase;
}
}
$base = new Base();
$base->initBase(new BaseSrc());
$base->init(new BaseSrc()); // WHY DOES IT WORK?????
class MainSrc extends BaseSrc
{
}
trait MainTrait
{
use BaseTrait {
BaseTrait::init as initBase;
}
public function init(MainSrc $mainSrc)
{
$this->initBase($mainSrc);
echo "Init Main";
}
}
// Warning: Declaration of MainTrait::init(MainSrc $mainSrc) should be compatible with Base::init(BaseSrc $baseSrc)
class Main extends Base
{
use MainTrait;
}
我认为,这段代码应该可行。自从我在init()
类中将initBase()
重命名为Base
并在BaseTrait
内使用MainTrait
时进行了相同的重命名,我希望这种方法({{1} }})不会与BaseTrait::init()
发生冲突。事实上,PHP说我有不兼容的声明。其背后的原因是重命名MainTrait::init()
不起作用 - 方法init as initBase
仍在我的init
类中!
如果不从一开始就将BaseTrait :: init()重命名为BaseTrait :: initBase()(而不仅仅是Base
语句),有没有办法解决这个问题?
我应该将此视为PHP错误并报告吗?这种行为背后有什么合理的吗?
答案 0 :(得分:0)
正如评论中所述和完整性;来自PHP manual section on Traits:
Aliased_Talker
使用as运算符可以使用 B的bigTalk
实施另外的别名谈话。
然后:
as运算符可用于为其中一个方法添加别名。 请注意,as运算符不会重命名该方法,也不会影响该方法 任何其他方法。
因此as
添加了别名,但不会以任何方式替换或影响原始方法。这是预期的行为。