Вызовы, использующие parent :: или self ::, считаются статическими. Предполагается, что они будут оцениваться в контексте определяющего класса, а не в области вызывающего объекта. PHP 5.3 добавляет новое значение к слову static , которое будет доступно для статических вызовов , таких как parent и self, но будет оцениваться в контексте вызывающего класса . Это называется Позднее статическое связывание . Больше информации на этой странице:
http://www.php.net/lsb
Edit:
После некоторых размышлений я считаю, что это поведение вполне приемлемо. Во-первых, давайте посмотрим, почему A хочет, чтобы его метод foo () вызывал метод foo () своего родителя, учитывая, что у A нет родителя. Потому что он хочет, чтобы метод всегда выполнялся независимо от реализации дочерних элементов. Если так, то есть и другие решения, хотя и не такие приятные:
class A
{
final public function __construct()
{
echo __METHOD__;
$this->foo();
$init = array($this, 'init');
$args = func_get_args();
call_user_func_array($init, $args);
}
// init would be used as a pseudo-constructor in children
public function init()
{}
final private function foo()
{
echo __METHOD__;
}
}
class B extends A
{}
class C extends B
{}
$c = new C;
Если вы пытались выполнить каждый метод foo () в цепочке, то это было ожидаемое поведение. Если бы существовала функция B :: foo (), то она была бы выполнена, и если бы она содержала вызов parent :: foo (), то A :: foo () также была бы выполнена.
Так что, вероятно, parent :: foo () как-то сбивает с толку. Это должно быть прочитано как (извините, но я не мог найти лучший пример):
the_first_parent_in_the_inheritance_chain_which_has_a_foo_method :: Foo ()
Это то, что вас на самом деле интересует. Почему вы хотите вызывать foo () в контексте B? Единственная причина, по которой я могу придумать, - получить доступ к частному члену из B. Но тогда как A узнает, что есть у частных членов B? Не может Вы не можете использовать члены A :: foo (), которые A не объявил. Если A не является абстрактным и определяет некоторые абстрактные методы. Конечно, A может объявить это свойство как личное (B не может дать переопределенному члену более низкую видимость, чем в родительском, и наша цель состоит в том, чтобы B имел приватное).
Затем B переопределяет это свойство, делая его приватным, как мы хотим. Теперь, если бы ваш код работал, A или C имели бы доступ к приватному члену B, хотя это не должно было быть. Это нарушает правило.
Есть ли ситуации, в которых вам нужно поведение, о котором вы спрашивали?