Давайте займемся исследованием примеров этих двух случаев. Рассмотрим для начала полиморфную структуру данных, такую как список геометрических фигур:
figlist: LIST [FIGURE]
В предыдущих лекциях рассматривалась иерархия наследования фигур. Пусть нам необходимо найти самую длинную диагональ среди всех прямоугольников списка (и вернуть -1, если прямоугольников нет). Сделать это непросто. Выражение
Теперь пример второго рассматриваемого случая. Пусть имеется механизм хранения объектов в файле или передачи их по сети, аналогичный универсальному классу
my_last_book: BOOK
...
my_last_book := retrieved (my_book_file)
Значение, возвращаемое
Даже если написать собственную функцию
Проблема
Из этих примеров ясно: нам может понадобиться механизм удостоверения типа объекта.
Решение этой проблемы, возникающей в специфических, но критически важных случаях, должно быть найдено без потери преимуществ ОО-стиля разработки. В частности, мы не хотим возвращаться к той схеме, которую сами и осудили:
if "f типа RECTANGLE" then
...
elseif "f типа CIRCLE" then
...
и т.д.
Это решение идет вразрез с принципами Единственного Выбора и Открыт-Закрыт. Избежать риска потерь нам помогут два обстоятельства.
[x]. Нет смысла создавать универсальный механизм выяснения типа объектов. В том и другом случае тип объекта предположительно известен. Все, что нам нужно, - это способ проверки гипотезы. Определение принадлежности объекта данному типу носит более частный характер, чем запрос на определение типа. Кроме того, нам не требуется вводить в наш язык никаких операций над типами, к примеру, их сравнение - ужасающая мысль.
[x]. Как уже говорилось, мы не должны влиять на правило Вызова Компонентов. Ни при каких обстоятельствах мы не должны проверять применимость вызова компонента, если класс прошел статистическую проверку. Все, что нам нужно, - это более свободная версия другого правила - правила совместимости типов, позволяющая "испытать тип" и проверить результат.
Механизм решения
И снова запись механизма решения напрямую вытекает из анализа поставленной проблемы. Введем новую форму присваивания, назвав ее попыткой присваивания (assignment attempt):
target ?= source
Знак вопроса указывает на предварительный характер операции. Пусть сущность
[x]. если
[x]. иначе (если
На эту инструкцию не действуют никакие ограничения типов, кроме одного: тип
Новое средство быстро и элегантно решает поставленные проблемы и, прежде всего, дает возможность обращаться к объектам полиморфной структуры с учетом их типа:
maxdiag (figlist: LIST [FIGURE]): REAL is
-- Максимальная длина диагонали прямоугольника в списке;
-- если прямоугольников нет, то -1.
require
list_exists: figlist /= Void
local
r: RECTANGLE
do
from
figlist.start; Result := -1.0
until
figlist.after
loop
r ?= figlist.item
if r /= Void then
Result := Result.max (r.diagonal)
end
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии