PHP: Погружаясь в классы
Теория: Динамическая диспетчеризация
В курсе "PHP: Полиморфизм" мы разбирали как работает полиморфизм изнутри. Но тогда мы ещё не знали про наследование достаточно, чтобы раскрыть этот вопрос полностью. Сейчас пришло время узнать об этом.
Перед тем как начать, нужно вспомнить, что для полиморфизма наследование не нужно. С другой стороны, наследование участвует в процессе выбора метода и об этом тоже нужно знать. Посмотрите на код, который был в курсе, посвящённому полиморфизму:
В этом коде проверка останавливается, если ничего не было найдено. Так было бы без наследования, но с наследованием поиск продолжается. Сначала выбирается базовый класс для текущего и метод ищется там. Если он не найден, то снова проверяется наличие __call(). Затем процесс повторяется для родительского класса родителя текущего класса и далее до конца цепочки наследования.
Из этого, кстати, следует интересный вывод. Метод __call это "тяжелый" вызов. Он требует больше вычислений для поиска. И чем ближе к началу иерархии расположен __call() тем хуже с точки зрения производительности.
Позднее связывание в сравнении с динамической диспетчеризацией
Программисты часто путают позднее связывание и динамическую диспетчеризацию. Ситуация усугубляется тем, что в некоторых языках (например, Java) принято на уровне документации и сообщества подменять одно понятие другим.
Связывание говорит нам о том, чем является идентификатор, какой у него тип. Если связывание раннее, то мы это знаем сразу, в случае позднего, только в момент вызова кода. Во многих языках можно определить функцию после того, как где-то она используется. Это тоже пример связывания (позднего). В случае $this в PHP, мы знаем что это объект текущей иерархии, но не знаем точно какой класс до момента срабатывания этого кода.
Диспетчеризация же, это процесс поиска и вызова необходимой функции (или метода, в зависимости от языка) для уже известного типа данных.
.png)

