indexing
description: 'Новый вариант с параллельными иерархиями'
class SKIER1 feature
accommodation: ROOM
accommodate (r: ROOM) is ... require ... do
accommodation:= r
end
end
Здесь также необходимы ковариантные переопределения: в классе
Своенравие полиморфизма
Не довольно ли примеров, подтверждающих практичность ковариации? Почему же кто-то рассматривает контравариантность, которая вступает в противоречие с тем, что необходимо на практике (если не принимать во внимание поведения некоторых молодых людей)? Чтобы понять это, рассмотрим проблемы, возникающие при сочетании полиморфизма и стратегии ковариантности. Придумать вредительскую схему несложно, и, возможно, вы уже создали ее сами:
s: SKIER; b: BOY; g: GIRL
...
create b; create g;-- Создание объектов BOY и GIRL.
s := b; -- Полиморфное присваивание.
s.share (g)
Результат последнего вызова, вполне возможно приятный для юношей, - это именно то, что мы пытались не допустить с помощью переопределения типов. Вызов
Схема с параллельной иерархией столь же проста: заменим
При контравариантном решении этих проблем не возникало бы: специализация цели вызова (в нашем примере
В литературе для программистов нередко встречается призыв к методам, основанных на простых математических моделях. Однако математическая красота - всего лишь один из критериев ценности результата, - есть и другие - полезность и реалистичность. |
Поэтому, не пытаясь натянуть контравариантную одежду на ковариантное тело, следует принять ковариантную действительность и искать пути устранения нежелательного эффекта.
Скрытие потомком
Прежде чем искать решение проблемы ковариантности, рассмотрим еще один механизм, способный в условиях полиморфизма привести к нарушениям типа. Скрытие потомком (descendant hiding) - это способность класса не экспортировать компонент, полученный от родителей.
Рис. 17.8. Скрытие потомком
Типичным примером является компонент
class RECTANGLE inherit
POLYGON
export {NONE} add_vertex end
feature
...
invariant
vertex_count = 4
end
Не программистский пример: класс 'Страус' скрывает метод 'Летать', полученный от родителя 'Птица'.
Давайте на минуту примем эту схему такой, как она есть, и поставим вопрос, будет ли легитимным сочетание наследования и скрытия. Моделирующая роль скрытия, подобно ковариантности, нарушается из-за трюков, возможных из-за полиморфизма. И здесь не трудно построить вредоносный пример, позволяющий, несмотря на скрытие компонента, вызвать его и добавить прямоугольнику вершину: