Читаем Основы объектно-ориентированного программирования полностью

Переопределение может повлиять на реализацию компонента, его сигнатуру (тип аргументов и результата) и спецификацию.

Должно быть возможным переопределить спецификацию, сигнатуру и реализацию наследованного компонента.

<p>Полиморфизм</p>

При наследовании, требование статической типизации, о котором говорилось выше, становится ограничивающим, если бы оно означало, что каждая сущность типа C может быть связана только с объектом точно такого же типа С. Например в системе управления навигацией сущность типа BOAT нельзя было бы использовать для объектов класса MERCHANT_SHIP или SPORTS_BOAT, хотя оба класса являются потомками класса BOAT.

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

Полиморфизм (polymorphism) - способность присоединять к сущности объекты различных возможных типов. В статически типизированной среде полиморфизм не будет произвольным, а будет контролироваться наследованием.

Должна иметься возможность в период выполнения присоединять к сущности объекты различных возможных типов под управлением наследования.

<p>Динамическое связывание</p>

Сочетание последних двух механизмов, переопределения и полиморфизма, непосредственно предполагает следующий механизм. Допустим, есть вызов, целью которого является полиморфная сущность, например сущность типа BOAT вызывает компонент turn. Различные потомки класса BOAT, возможно, переопределили этот компонент различными способами. Ясно, что должен существовать автоматический механизм, гарантирующий, что версия turn всегда соответствует фактическому типу объекта, вне зависимости от того, как объявлена сущность. Эта возможность называется динамическим связыванием (dynamic binding).

Вызов сущностью компонента всегда должен запускать тот компонент, который соответствует типу присоединенного объекта, а не типу сущности.

При различных выполнениях одного и того же вызова могут запускаться разные компоненты.

Динамическое связывание оказывает большое влияние на структуру ОО-приложения, поскольку дает возможность разработчикам писать простые вызовы, например объект my_boat вызывает компонент turn. В действительности, данный вызов означает несколько возможных вызовов, зависящих от соответствующих ситуаций времени выполнения. Это упраздняет необходимость многих повторных проверок (является ли объект merchant_ship? Является ли он sports_boat?), наводняющих программные продукты, создаваемые при обычных подходах.

<p>Выяснение типа объекта в период выполнения </p>

Разработчики ОО-ПО вскоре вырабатывают здоровую неприязнь к любому стилю вычислений, основанному на явном выборе между различными типами объекта. Полиморфизм и динамическое связывание намного предпочтительнее. Однако в некоторых случаях объект приходит извне, так что автор ПО не имеет возможности с определенностью предсказать его тип. В частности, это случается, если объект извлекается из внешних хранилищ, получен по сети или передан некоторой другой системой.

Тогда ПО нуждается в механизме, обеспечивающем безопасный способ доступа к объекту без нарушения ограничений статической типизации. Такой механизм должен проектироваться с большой аккуратностью, так чтобы не утратить пользы от полиморфизма и динамического связывания.

Операция попытка присваивания (assignment attempt) удовлетворяет этим требованиям. Это условная операция: она пытается присоединить объект к сущности; если при выполнении операции тип объекта соответствует типу сущности, то она действует как нормальное присваивание; в противном случае сущность получает специальное значение void. Итак, можно управлять объектами, тип которых не известен наверняка, не нарушая безопасности системы типов.

Необходимо иметь возможность определять во время выполнения, соответствует ли тип объекта статически заданному типу.

<p>Отложенные (deferred) свойства и классы</p>
Перейти на страницу:

Похожие книги