我使用 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()
into initBase()
in the Base
类并在使用时进行相同的重命名BaseTrait
inside MainTrait
,我期望这个方法(BaseTrait::init()
)不会与MainTrait::init()
。事实上,PHP 说我有不兼容的声明。其背后的原因是更名init as initBase
不起作用 - 方法init
仍然在那里,在我的Base
class!
有什么方法可以解决这个问题,而无需从一开始就将 BaseTrait::init() 重命名为类似 BaseTrait::initBase() 的东西(不仅仅是在use
陈述)?
我应该将此视为 PHP 错误并报告吗?这种行为背后有什么合理的理由吗?
正如评论中提到的和为了完整性;来自PHP 手册中有关 Traits 的部分 http://php.net/manual/en/language.oop5.traits.php:
The Aliased_Talker
利用 as 运算符能够使用
乙的bigTalk
在额外的别名下实现谈话。
进而:
as 运算符可用于向其中一种方法添加别名。
请注意,as 运算符不会重命名该方法,并且不会影响
任何其他方法也可以。
So as
添加别名,但不会以任何方式替换或影响原始方法。这是预期的行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)