私は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のバグとみなして報告する必要がありますか?この行動の背後に妥当なものはありますか?
php.netは次のように書いています: 'Aliased_Talkerは、**追加の'エイリアストーク 'の下でBのbigTalk実装を使用できるas演算子を使用します。 - http://php.net/manual /en/language.oop5.traits.php。したがって、 'as'はエイリアスを追加しますが、メソッドを置き換えません。そして: 'as演算子を使ってメソッドの1つにエイリアスを追加することができます。 as演算子はメソッドの名前を変更せず、他のメソッドにも影響しないことに注意してください。 '' – splash58
@ splash58ありがとう、ありがとう。私は "as"の名前を変更していない、それはちょうど "エイリアシング"(正直言って、私はこの特記事項についてのこのページを読んでいる間はこのメモに言及しなかった)です。それの背後に理由はありますか?つまり、名前を変更する代わりにエイリアシングの利点がありますか?私の見地からは、非常に不便です。 – Dm9
私は '代わりに'あなたが欲しいものを作ると思います。私が間違っている?私はとても深い形質を持っていません – splash58