Пытаясь отлаживать некоторые классы PHP, я столкнулся с некоторым поведением, которое, на мой взгляд, действительно странно.
Я построил демонстрацию поведения ниже:
class BaseClass {
public function baseMethod () {
echo (implode (' ', $this -> childMethod ()) . PHP_EOL);
}
}
class ChildClass extends BaseClass {
protected function childMethod () {
return array ('What', 'The', 'Actual', 'Fork!');
}
}
$a = new ChildClass ();
$a -> baseMethod ();
Теперь, на мой взгляд, базовый класс вообще не должен иметь возможности делать какие-либо предположения о подклассе, кроме тех, которые он применяет для подкласса, объявляя (или наследуя) абстрактные методы или реализуя интерфейс. Однако приведенный выше код фактически выводит строку и не выдает никаких ошибок!
Какая настоящая вилка!
Это кажется мне нарушенным поведением. Если базовый класс не объявит abstract protected function childMethod();
, он не сможет его вызвать, не так ли?
Я искал в Интернете, чтобы попытаться найти что-то, что демонстрирует ожидаемое поведение. Пока все, что мне удалось найти, это следующее из руководства по PHP:
Видимость с других объектов
Объекты одного типа будут иметь доступ к закрытым и защищенным членам друг друга, даже если они не являются одними и теми же экземплярами. Это связано с тем, что конкретные детали реализации уже известны, когда они находятся внутри этих объектов.
Так правильно ли поведение, которое я здесь наблюдаю, или это ошибка в PHP? Это определенно не то поведение, на которое я бы полагался, потому что оно кажется мне неправильным.
К вашему сведению, проблема, которую мы обнаружили в реальном коде, заключалась в том, что подкласс объявил закрытый метод, который суперкласс пытался вызвать. Суперкласс не объявлял абстрактный метод (а если бы и сделал, то должен был бы быть как минимум защищен).
$this
является ссылкой на вызывающий объект (ChildClass
в вашем примере), у которого есть методchildMethod
, поэтому скрипт работает. Я бы сказал, что это технически возможно, но это плохая практика. - person Leri   schedule 29.01.2013$this
относится к объекту, а не к самому классу. Тамself
относится к текущему классу. - person Leri   schedule 29.01.2013