PHP の奇妙な継承の問題と思われるものを見つけました。
保護されていると宣言されたメンバーは、クラス自体内で、継承されたクラスおよび親クラスによってのみアクセスできます。
私にとってこれは、A が B の保護されたメンバーにアクセスできることを意味しA instanceof B
ますB instanceof A
。
ただし、A と B の両方が Foo を拡張し、Foo に B で上書きされない保護されたコンストラクターがある場合、A 内から B のインスタンスを作成できます。A は のインスタンスではないため、これは意味がありません。 B であり、B は A のインスタンスではありません。A$b->test()
内から保護されたメソッドを呼び出して、B で実装されたメソッドを実行することもできます (B が再宣言されない場合test()
、Foo での実装が実行されます)。 B が保護されたコンストラクターを直接実装する場合、A 内から B のインスタンスを作成できないため、奇妙です。保護されたコンストラクター (親クラスでも宣言されている) にアクセスできないのは奇妙に思えますが、保護されたメソッド (親クラスでも宣言されています) にアクセスすることは問題ありません。
Foo を拡張しないクラス C を使用すると、期待どおりの動作が得られることに注意してください。C 内から B をインスタンス化しようとすると、保護されたコンストラクターにアクセスしようとしているため、致命的なエラーが発生します。パブリック コンストラクターを B に追加すると、それをインスタンス化することができますが (これは予想されます)、保護されたメソッドにアクセスすることはできませんtest()
(これも予想される動作です)。C の代わりに A を使用すると、同じ動作が期待されます。
もう一度説明するサンプルコード:
class Foo {
protected function __construct() {
echo('Constructing ' . get_called_class());
}
protected function test() {
echo('Hello world ' . __METHOD__);
}
}
class A extends Foo {
public function __construct() {
parent::__construct();
}
public function testB() {
// Both of these lines work
$b = new B();
$b->test();
}
}
class B extends Foo {
protected function test() {
echo('Hello world Again ' . __METHOD__);
}
}
class C {
public function __construct() {
}
public function testB() {
// Both of these lines cause fatal errors
$b = new B();
$b->test();
}
}
$a = new A();
$a->testB();
$c = new C();
$c->testB();
私はおそらく何かを見ていませんが、何を見つけることができません。誰かが私に行動を説明できますか?