В курсе "php: полиморфизм", мы разбирали как работает полиморфизм изнутри. Но тогда, мы еще не знали про наследование достаточно, чтобы раскрыть этот вопрос полностью. Теперь время пришло.

Перед тем как начать, нужно вспомнить что для полиморфизма наследование не нужно. С другой стороны, наследование участвует в процессе выбора метода и об этом тоже нужно знать. Посмотрите на код, который был в курсе посвященному полиморфизму:

<?php

// Что происходит во время вызова: $obj->getName() => callMethod($obj, 'getName')
function callMethod($data, $methodName, $args) // функция диспетчер
{
    $className = $data['className']
    // Специальная функция, которая хранит список классов и связанных с ними методов
    $methods = getClassMethods($className);
    // Берем нужный метод и вызываем его
    $method = $methods[$methodName]
    if ($method) {
      $method($data, ...$args);
    } else if (!$method && isset($methods['__call'])) {
      // Если метод $method не найден, но определен метод __call, то вызываем его
      $methods['__call']($data, ...$args);
    }

    throw new \Exception('No method error');
}

В этом коде, проверка останавливается если ничего не было найдено. Так было бы без наследования, но с наследованием поиск продолжается. Сначала выбирается базовый класс для текущего и метод ищется там. Если он не найден, то снова проверяется наличие __call. Затем процесс повторяется для родительского класса родителя текущего класса и далее до конца цепочки наследования.

Late Binding vs Dynamic Dispatch

Программисты часто путают позднее связывание и динамическую диспетчеризацию. Ситуация усугубляется тем, что в некоторых языках (например Java), принято на уровне документации и сообщества подменять одно понятие другим.

Связывание, говорит нам о том, чем является идентификатор, какой у него тип. Если связывание раннее, то мы это знаем сразу, в случае позднего, только в момент вызова кода. Во многих языках можно определить функцию, после того, как где-то описано ее использование. Это тоже пример связывания (позднего). В случае $this в PHP, мы знаем что это объект текущей иерархии, но не знаем точно какой класс до момента срабатывания этого кода.

Диспетчеризация же, это процесс поиска и вызова необходимой функции (или метода, в зависимости от языка) для уже известного типа данных.


Дополнительные материалы

  1. What is early and late binding?

Для продолжения нужно перейти в курс и вступить в него.