我使用PHP 7.1.0。为什么重命名方法在PHP特征中不起作用?
比方说,我们有一个特点,我们用它在类中,并重新命名导入的方法:
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()
更名为,Base
类别,并且在MainTrait
内使用BaseTrait
进行了相同的重命名,我预计此方法(BaseTrait::init()
)不会与MainTrait::init()
冲突。事实上,PHP说我有不兼容的声明。其背后的原因是,重命名init as initBase
不起作用 - 方法init
仍然存在,在我Base
类!
有没有什么办法如何解决这个问题,而不从BaseHrait :: initBase()开始(不仅仅是在use
声明中)重命名BaseTrait :: init()?
我应该考虑这是一个PHP错误,并报告了吗?这种行为背后有什么合理的吗?
写什么php.net:'的Aliased_Talker利用了作为运营商能够使用an' ** **附加'别名talk.'下B的bigTalk实现 - http://php.net/manual /en/language.oop5.traits.php。所以'as'增加了别名,但不能代替方法。然后:'as运算符可以用来向其中一个方法添加别名。请注意,as运算符不会重命名该方法,也不会影响任何其他方法。'' – splash58
@ splash58好的,谢谢。我看到:“as”不是重命名,它只是“别名”(说实话,在阅读这个关于特性的页面时,我没有提到这个注释)。背后有理由吗?我的意思是,别名的任何优点,而不是重命名?从我的角度来看,这很不方便。 – Dm9
我认为'而不是'做出你想要的。我错了吗?我不知道特质如此之深 – splash58