我使用
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?
这真的很痛苦,因为在更复杂的示例中,您不能依赖于方法重命名 – 因此您可能会意外地收到“不兼容的声明”错误:
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; }
我认为,这段代码应该可行.由于我在Base类中将init()重命名为initBase()并在MainTrait中使用BaseTrait时进行相同的重命名,我希望此方法(BaseTrait :: init())不会与MainTrait :: init()冲突.事实上,PHP说我有不兼容的声明.其背后的原因是将init重命名为initBase不起作用 – 在我的Base类中,方法init仍然存在!
有没有办法如何解决这个问题,而不是从一开始就将BaseTrait :: init()重命名为BaseTrait :: initBase()(不仅仅是在use语句中)?
正如评论中所述和完整性;从
PHP manual section on Traits:
The
Aliased_Talker
makes use of the as operator to be able to use
B’sbigTalk
implementation under an additional alias talk.
然后:
The as operator can be used to add an alias to one of the methods.
Note the as operator does not rename the method and it does not affect
any other method either.