2017-05-07 38 views
6

我使用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错误,并报告了吗?这种行为背后有什么合理的吗?

+1

写什么php.net:'的Aliased_Talker利用了作为运营商能够使用an' ** **附加'别名talk.'下B的bigTalk实现 - http://php.net/manual /en/language.oop5.traits.php。所以'as'增加了别名,但不能代替方法。然后:'as运算符可以用来向其中一个方法添加别名。请注意,as运算符不会重命名该方法,也不会影响任何其他方法。'' – splash58

+0

@ splash58好的,谢谢。我看到:“as”不是重命名,它只是“别名”(说实话,在阅读这个关于特性的页面时,我没有提到这个注释)。背后有理由吗?我的意思是,别名的任何优点,而不是重命名?从我的角度来看,这很不方便。 – Dm9

+0

我认为'而不是'做出你想要的。我错了吗?我不知道特质如此之深 – splash58

回答

0

正如评论和完整性提到的;从PHP manual section on Traits

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk 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.

所以as增加了一个别名,但不会取代或以任何方式影响原来的方法。这是预期的行为。

相关问题