Мне всегда казалось, что я понимаю, как работает ООП (и я использую его годами), но иногда я понимаю, что некоторые концепции до сих пор мне не так понятны.
Я только что натолкнулся на этот вопрос о видимости метода в PHP. В принятом ответе объясняется, что закрытый метод не может быть переопределен дочерним классом в PHP. Хорошо, это имеет смысл. Однако этот пример заставил меня задуматься о механизме внутреннего наследования в PHP и о том, как $this
ведет себя на унаследованных методах.
Рассмотрим этот код ( пример из руководства по PHP , также включенного в вопрос, упомянутый выше):
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
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();
/*
Output:
Bar::testPrivate
Foo::testPublic
*/
Теперь рассмотрим этот отрывок из Руководства по PHP :
Псевдопеременная $ this доступна, когда метод вызывается из контекста объекта. $ это ссылка на вызывающий объект (обычно это объект, к которому принадлежит метод, но, возможно, другой объект, если метод вызывается статически из контекста вторичного объекта).
Объяснение гласит, что «$this
является ссылкой на вызывающий объект», то есть $myFoo
. Поэтому я ожидал, что $myFoo->test()
всегда будет вызывать Foo::testPrivate
и никогда Bar::testPrivate
(если $myFoo
не является экземпляром Bar
). Я тестировал $this
с get_class
, и он всегда возвращает Foo
, даже изнутри Bar::testPrivate
и Bar::test
. Однако $this
ведет себя как экземпляр Bar
, когда Bar::test
вызывает $this->testPrivate()
.
Это действительно сбивает с толку, и я пытаюсь понять , почему так работает!
Я думал, что унаследованные методы (public
или protected
) были каким-то образом скопированы из базового в дочерний класс. Частные методы не будут скопированы вообще. Но этот пример показывает, что это не работает так. Похоже, что экземпляр Foo
хранит внутренний экземпляр Bar
и делегирует вызовы методов при необходимости.
Я пытаюсь чему-то научиться здесь, и я учусь только тогда, когда вещи имеют для меня смысл. Этот не делает. После написания всего этого, я думаю, я могу обобщить это двумя вопросами:
Может ли кто-нибудь кратко объяснить, как работает наследование внутри в PHP? Или, по крайней мере, указать мне статью или документацию об этом?
Поведение или $this
, обсуждаемое здесь, присутствует и на других языках OO, или оно специфично для PHP?