2017-05-07 3 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クラスのinitBase()に改名したので、をMainTraitの内部に使用すると、同じ名前変更が行われました。このメソッド(BaseTrait::init())はMainTrait::init()と競合しません。実際、PHPには互換性のない宣言があると言われています。その背後にある理由は、init as initBaseという名前の変更が機能しないということです - 方法initはまだ私のBaseクラスにあります!

BaseTrait :: init()の名前をBaseTrait :: initBase()のようなものに変更することなく、この問題を解決する方法はありますか?(useステートメントだけでなく)

私はこれをPHPのバグとみなして報告する必要がありますか?この行動の背後に妥当なものはありますか?

+1

php.netは次のように書いています: 'Aliased_Talkerは、**追加の'エイリアストーク 'の下でBのbigTalk実装を使用できるas演算子を使用します。 - http://php.net/manual /en/language.oop5.traits.php。したがって、 'as'はエイリアスを追加しますが、メソッドを置き換えません。そして: 'as演算子を使ってメソッドの1つにエイリアスを追加することができます。 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エイリアスを追加しますが、どのような方法で元のメソッドを置き換えるか影響はありません。これは予想される動作です。

関連する問題