为什么方法重命名在PHP特征中不起作用?

问题描述 投票:8回答:1

我使用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时进行相同的重命名,我希望这种方法(BaseTrait::init())不会与MainTrait::init()冲突。事实上,PHP说我有不兼容的声明。其背后的原因是重命名init as initBase不起作用 - 方法init仍然存在,在我的Base类!

有没有办法如何解决这个问题,而不是从一开始就将BaseTrait :: init()重命名为BaseTrait :: initBase()(不仅仅是在use语句中)?

我应该将此视为PHP错误并报告吗?这种行为背后有什么合理的吗?

php traits
1个回答
0
投票

正如评论中所述和完整性;来自PHP manual section on Traits

Aliased_Talker利用as运算符能够在另外的别名谈话中使用B的bigTalk实现。

然后:

as运算符可用于向其中一个方法添加别名。请注意,as运算符不会重命名该方法,也不会影响任何其他方法。

所以as添加了一个别名,但不会以任何方式替换或影响原始方法。这是预期的行为。

© www.soinside.com 2019 - 2024. All rights reserved.