Закрытый метод переопределения и видимости
Я с трудом пытаюсь понять вывод следующего кода:
class Bar
{
public function test() {
$this->testPublic();
$this->testPrivate();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test();
Выход:
Foo::testPublic
Bar::testPrivate
Класс Foo переопределяет testPublic () и testPrivate () и наследует test (). Когда я вызываю test (), существует явная инструкция, включающая в себя псевдопеременную $ this, поэтому после того, как я создал экземпляр $ myFoo, последними вызовами функции test () будут $myFoo->testPublic() и $myFoo->testPrivate() Первый вывод, как я и ожидал, поскольку я переопределил метод testPublic (), чтобы повторить Foo:: testPublic. Но второй вывод не имеет смысла для меня. Почему это Bar::testPrivate, если я переопределил метод testPrivate ()? Также приватный метод из родительского класса не будет наследоваться в любом случае, по определению! Это не имеет никакого смысла. Почему родительский метод вызывается???
1 ответ
Проблема с вашим кодом в том, что метод Bar::testPrivate
является private
поэтому он не может быть переопределен дочерними классами. Для начала я рекомендую вам ознакомиться с видимостью в PHP - http://www.php.net/manual/en/language.oop5.visibility.php. Там вы узнаете, что только public
а также protected
методы / свойства членов класса могут быть переопределены, private
никто не может.
В качестве хорошего примера попробуйте изменить видимость Bar::testPrivate
метод либо публичный, либо защищенный, без каких-либо изменений в вашем примере кода. Теперь попробуйте запустить тесты. Что просходит? Это:
Неустранимая ошибка PHP: уровень доступа к Foo::testPrivate() должен быть защищен (как в классе Bar) или слабее
Большой вопрос: "почему?". Ну, ты переопределил Bar::testPrivate
с частным Foo:testPrivate
, Этот новый частный метод выходит за рамки Bar::test
потому что закрытые члены класса видны только их текущему классу, а НЕ родительским / дочерним классам!
Поэтому, как вы можете видеть, ООП обеспечивает определенную степень инкапсуляции для членов класса, и это может быть довольно запутанным, если вы не нашли время, чтобы понять это.