Наследование PHP и видимость защищенного члена
Я обнаружил что-то, что кажется странной проблемой наследования в PHP.
Members declared protected can be accessed only within the class itself and by inherited and parent classes.
Для меня это означает:
A может получить доступ к защищенным членам B, еслиA instanceof B
или жеB instanceof A
.
Однако если и A, и B расширяют Foo, а Foo имеет защищенный конструктор, который не перезаписывается в B, тогда я могу создать экземпляр B изнутри A. Это не имеет смысла для меня, поскольку A не является экземпляром B и B не является экземпляром A. Я также могу вызвать защищенный метод$b->test()
изнутри A, который выполняет метод, реализованный в B. (Если B не переопределитьtest()
затем выполняется реализация в Foo.) Для меня это еще более странно, потому что я не могу создать экземпляр B изнутри A, если B напрямую реализует защищенный конструктор. Кажется странным, что я не могу получить доступ к защищенному конструктору (также объявленному в родительском классе), но доступ к защищенному методу (также объявленному в родительском классе) не представляет проблемы.
Обратите внимание, что я получаю ожидаемое поведение, когда использую класс C, который не расширяет Foo. Если я пытаюсь создать экземпляр B изнутри C, я получаю фатальную ошибку, потому что я пытаюсь получить доступ к защищенному конструктору. Если я добавлю открытый конструктор в B, его можно создать (что ожидается), и я все еще не могу получить доступ к защищенному методуtest()
(это тоже ожидаемое поведение). Я ожидаю того же поведения при использовании A вместо C.
Пример кода, который объясняет еще раз:
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();
Я, вероятно, что-то не вижу, но я не могу найти что. Может ли кто-нибудь объяснить мне поведение?