2017-05-07 15 views
6

PHP 7.1.0 kullanıyorum.Neden PHP'nin özelliklerinde yöntem yeniden adlandırma çalışmıyor?

trait T 
{ 
    public function A() { 
     echo "."; 
    } 
} 

class C 
{ 
    use T { 
     A as B; 
    } 
} 

$c = new C(); 
$c->B(); 
$c->A(); // Why does it work? 

Neden PHP hala beni (bu durumda A) eski yöntem adı kullanmasına izin vermez:

en, bunun bir sınıf içerisindeki kullanmak ve ithal yöntemini adlandırmak bir özelliği var diyelim?

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; 
} 

Bence bu kod çalışması gerekir: ve böylece beklenmedik "uyumsuz bildirimleri" hatası alabilirsiniz - daha karmaşık örneklerde Eğer yöntem yeniden adlandırma güvenemez çünkü

Gerçekten acı. Base sınıfında init()initBase() olarak yeniden adlandırıldığı ve 'u kullanarak aynı yeniden adlandırma yaptığından, bu yöntemin (BaseTrait::init()) MainTrait::init() ile çakışmayacağını umuyorum. Aslında PHP, uyumsuz beyanlarım olduğunu söyledi. Bunun nedeni, init as initBase'un yeniden adlandırılmasının işe yaramamasıdır - init yöntemi hala burada, benim Base sınıfımda!

BaseTrait :: init() işlevini BaseTrait :: initBase() gibi bir şeye dönüştürmeksizin (yalnızca use deyiminde değil) bu sorunu nasıl çözebiliriz?

Bunu bir PHP hatası olarak düşünmeli ve rapor etmeli miyim? Bu davranışın arkasında makul bir şey var mı?

+1

php.net hakkında ne yazıyor: 'Aliased_Talker, bir“ ** ek ** 'alias talk.' (http://php.net/manual) altındaki bigTalk uygulamasını kullanabilmek için as operatörünü kullanır. /en/language.oop5.traits.php. Yani '' takma ad ekler ama yöntemi değiştirmez. Ve sonra: 'operatör olarak yöntemlerden birine bir takma ad eklemek için kullanılabilir. As operatörünün yöntemi yeniden adlandırdığını ve diğer herhangi bir yöntemi etkilemediğini unutmayın. ' – splash58

+0

@ splash58 Tamam, teşekkürler. Görüyorum: "gibi" yeniden adlandırma değil, sadece "takma" (dürüst olmak gerekirse, bu notu özellikleri hakkında okurken bahsetmedim). Bunun arkasında bir sebep var mı? Demek istediğim, yeniden adlandırma yerine yeniden adlandırma avantajları var mı? Benim bakış açımdan, bu çok rahatsız edici. – Dm9

+0

Bence "istediğini yap" yerine. Yanlış mıyım? Bu kadar derinlikli – splash58

cevap

0

Yorumlar ve tamlık olarak belirtildiği gibi; PHP manual section on Traits Gönderen: ardından

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk implementation under an additional alias talk.

Ve:

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.

Yani as bir takma ad ekler ancak değiştirmek veya herhangi bir şekilde orijinal yöntemini etkilemez. Beklenen davranış budur.

İlgili konular