Наследование приватного метода и позднего статического связывания в php

Итак, я читал официальную документацию 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? Насколько я знаю, только публичные и защищенные свойства копируются в дочерний класс. Что мне не хватает?

1 ответ

Возможно, комментарий "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. - согласно сообщению об ошибке.

Другие вопросы по тегам