Так что я читал официальную документацию по PHP на Поздние статические привязки и наткнулся на запутанный пример:
<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //fails
?>
Вывод примера:
success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
Может кто-нибудь объяснить, почему закрытый метод foo () копируется в B? Насколько я знаю, только публичные и защищенные свойства копируются в дочерний класс. Что мне не хватает?
Возможно, комментарий «foo () будет скопирован в B» немного запутан или неправильно интерпретирован. Функция foo () по-прежнему закрыта для A и доступна только из методов в A.
то есть. В примере, если вы пытаетесь выполнить$b->foo()
его все равно не получится, как ожидалось.
Это, как я объяснил пример для себя и, возможно, будет полезно для других:
Учитывая класс B.
$b->test()
имеет доступ к foo () как открытый член A.
$this->foo()
также преуспевает в $b->test()
$static::foo()
успешно, потому что он вызывает версию foo (), определенную в A, из test (), которая также определена в A. Нет конфликта областей видимости.
Учитывая класс B.
Когда foo () переопределяется в классе C,
$c->test()
конечно, все еще доступен как публичный член, если А.
и внутри $c->test()
$ this-> foo () доступен как закрытый член A. — все хорошо.
НО
$static::foo()
в настоящее время пытается получить доступ из A, версия foo (), определенная в классе C, и поэтому терпит неудачу, потому что она закрыта для C. — согласно сообщению об ошибке.
Других решений пока нет …