Привет всем. У меня такой вопрос возник: может кто написать НОРМАЛЬНЫМ ЯЗЫКОМ, подробно, алгоритм наследования в PHP? Прост на всех сайтах пишется обычно одно и то же: "Наследование - это расширение существующего класса, при котором потомок может использовать не только свои свойства и методы, но и родителя (не все, учитываются модификаторы доступа)".
Мне это понятно, но вопрос у меня будет стоять глубже. Я делал много тестов с наследованием, и каждый раз входил в ступор и не понимал, почему именно так это работает. Вроде бы логически правильно, но понять алгоритм, по которому работает интерпретатор - не могу. То есть не пойму, КАК ИМЕННО работает наследование.
Рассмотрим пример:
class A {
private $k = 1;
public function check() {
return $this->k;
}
}
class B extends A {
public $k = 5;
}
$o = new B();
echo $o->check();
В данном коде программа выведет 1. Подумайте, почему (но я сам не до конца понимаю, вот и спрашиваю). Да, можно сказать, мол: "Ну, тут приватное свойство, оно не наследуется, поэтому метод check выводит свойство родителя со значением 1, а не 5 с потомка". НО. Если поставить метод в дочерний класс, убрав с родителя, то выведется 5. Вы, возможно, скажите: "Ну, тут просто метод находится в потомке, поэтому он в приоритет берет свойство, записанное в нем же, да и взять private он не может, так как тот не наследовался. Кроме того, свойство k в потомке здесь считается отдельным, никак не связанным со свойством родительского класса, так как, опять же, k не наследовался". Но смотрите: private не наследовался в двух вариантах, однако в 1 варианте выводится именно private свойство. На многих сайтах говорят, что при наследовании "копируется содержимое" из родительского класса в потомок, либо наоборот. Но если бы это было так, тогда private бы не скопировался, и программа в обоих случаях должна была бы выдать ответ 5. Но тут зависит от того, с какого класса вызывается метод. То есть, существуют определенные правила при наследовании, упоминание которых я пока не встречал на сайтах. В нашем примере можно предположить, что вызов чего-либо (в нашем случае $this->k) приоритетен там, в каком классе он был вызван. Тогда вроде все хорошо. Но заменим свойство родителя на public в коде выше. Теперь, получается, при вызове метода получится 1, однако это противоречит высказыванию выше про приоритет. Вы скажете, что свойство переопределилось: да, согласен. Но в какой момент? Когда создавался класс или объект? И как понять "переопределилось"? Значение в родителе изменилось? Или же родительское свойство "удалилось" (образно говорю, чтобы хоть как-то понимать принцип работы), а осталось только дочернее? Ну или оно осталось и там, и там, но в родителе просто изменилось значение? Или под этим словом вообще совсем другое понимают? Допустим, что это так. Но теперь удалим приватное свойство с родителя. Теперь в родителе не останется свойства k, и программа вызовет метод check, но по моей логике интерпретатор должен искать именно в этом классе значение, но он его не найдет, ведь оно в дочернем. Получается, что если не находятся где-либо нужные данные, то они ищутся в другом классе? Сначала в приоритетном - где был вызван - а потом в другом?
Мне кажется, что это не так, что я уже давным давно в рассуждениях ошибаюсь. Потому что это слишком запутанно и криво. И я хочу, чтобы хоть кто-нибудь мне объяснил, как именно всё это работает, это гребаное наследование. И да, попробуйте в программе, которую я написал выше, заменить доступы свойств родителя и наследника наоборот. Тогда программа выдаст ошибку с просьбой поставить дочернему классу public свойство. А почему так нельзя? И т. д., и т. п., и у меня мозги кипят. Помогите, пожалуйста.
Мне это понятно, но вопрос у меня будет стоять глубже. Я делал много тестов с наследованием, и каждый раз входил в ступор и не понимал, почему именно так это работает. Вроде бы логически правильно, но понять алгоритм, по которому работает интерпретатор - не могу. То есть не пойму, КАК ИМЕННО работает наследование.
Рассмотрим пример:
class A {
private $k = 1;
public function check() {
return $this->k;
}
}
class B extends A {
public $k = 5;
}
$o = new B();
echo $o->check();
В данном коде программа выведет 1. Подумайте, почему (но я сам не до конца понимаю, вот и спрашиваю). Да, можно сказать, мол: "Ну, тут приватное свойство, оно не наследуется, поэтому метод check выводит свойство родителя со значением 1, а не 5 с потомка". НО. Если поставить метод в дочерний класс, убрав с родителя, то выведется 5. Вы, возможно, скажите: "Ну, тут просто метод находится в потомке, поэтому он в приоритет берет свойство, записанное в нем же, да и взять private он не может, так как тот не наследовался. Кроме того, свойство k в потомке здесь считается отдельным, никак не связанным со свойством родительского класса, так как, опять же, k не наследовался". Но смотрите: private не наследовался в двух вариантах, однако в 1 варианте выводится именно private свойство. На многих сайтах говорят, что при наследовании "копируется содержимое" из родительского класса в потомок, либо наоборот. Но если бы это было так, тогда private бы не скопировался, и программа в обоих случаях должна была бы выдать ответ 5. Но тут зависит от того, с какого класса вызывается метод. То есть, существуют определенные правила при наследовании, упоминание которых я пока не встречал на сайтах. В нашем примере можно предположить, что вызов чего-либо (в нашем случае $this->k) приоритетен там, в каком классе он был вызван. Тогда вроде все хорошо. Но заменим свойство родителя на public в коде выше. Теперь, получается, при вызове метода получится 1, однако это противоречит высказыванию выше про приоритет. Вы скажете, что свойство переопределилось: да, согласен. Но в какой момент? Когда создавался класс или объект? И как понять "переопределилось"? Значение в родителе изменилось? Или же родительское свойство "удалилось" (образно говорю, чтобы хоть как-то понимать принцип работы), а осталось только дочернее? Ну или оно осталось и там, и там, но в родителе просто изменилось значение? Или под этим словом вообще совсем другое понимают? Допустим, что это так. Но теперь удалим приватное свойство с родителя. Теперь в родителе не останется свойства k, и программа вызовет метод check, но по моей логике интерпретатор должен искать именно в этом классе значение, но он его не найдет, ведь оно в дочернем. Получается, что если не находятся где-либо нужные данные, то они ищутся в другом классе? Сначала в приоритетном - где был вызван - а потом в другом?
Мне кажется, что это не так, что я уже давным давно в рассуждениях ошибаюсь. Потому что это слишком запутанно и криво. И я хочу, чтобы хоть кто-нибудь мне объяснил, как именно всё это работает, это гребаное наследование. И да, попробуйте в программе, которую я написал выше, заменить доступы свойств родителя и наследника наоборот. Тогда программа выдаст ошибку с просьбой поставить дочернему классу public свойство. А почему так нельзя? И т. д., и т. п., и у меня мозги кипят. Помогите, пожалуйста.