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

Разница между этими двумя формами повторного объявления хорошо иллюстрируется примерами, приведенными при их определении:

[x]. При переходе от POLYGON к RECTANGLE компонент perimeter уже реализован у родителя, и мы хотим предложить новую его реализацию в классе RECTANGLE. Это переопределение. Заметим, что этот компонент еще раз переопределяется в классе SQUARE.

[x]. При переходе от FIGURE к POLYGON у родителя нет реализации компонента rotate, и мы хотим реализовать его в классе POLYGON. Это эффективизация. Собственные потомки POLYGON могут, конечно, переопределить эту эффективную версию.

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

Повторное объявление компонента кПовторное объявление компонента от
ОтложенныйЭффективный
ОтложенныйПереопределениеОтмена определения
ЭффективныйЭффективизацияПереопределение

Таблица 14.1.Эффекты повторного объявления

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

<p>Отложенные классы</p>

Как мы видели, компонент может быть отложенным или эффективным. То же относится и к классам.

Определение: отложенный класс, эффективный класс

Класс является отложенным, если у него имеется отложенный компонент.

В противном случае, класс является эффективным.

Таким образом, чтобы класс был эффективным, должны быть эффективными все его компоненты. Один или несколько отложенных компонентов делают класс отложенным. В этом случае класс должен содержать специальную метку:

Правило объявления отложенного класса

Объявление отложенного класса должно включать подряд идущие ключевые слова deferred class (в отличие от одного слова class для эффективных классов).

Поэтому класс FIGURE будет объявлен следующим образом:

deferred class FIGURE feature

rotate (...) is

... Объявления отложенных компонентов ...

... Объявления других компонентов ...

end

Обратно, если класс отмечен как отложенный, то у него должен быть хотя бы один отложенный компонент. При этом класс может быть отложенным, даже если в нем самом не объявлен ни один отложенный компонент, так как у него может быть отложенный родитель, от которого он унаследовал отложенный компонент, не ставший у него эффективным. В нашем примере в классе OPEN_FIGURE, скорее всего, останутся отложенными компоненты display, rotate и многие другие, унаследованные от класса FIGURE, поскольку понятие незамкнутой фигуры не настолько конкретизировано, чтобы поддерживать стандартные реализации этих операций. Поэтому этот класс является отложенным и будет объявлен как

deferred class OPEN_FIGURE inherit

FIGURE

...

даже если в нем самом не вводится ни один отложенный компонент.

Потомок отложенного класса является эффективным классом, если все отложенные компоненты его родителей имеют в нем эффективные определения и в нем не вводятся никакие собственные отложенные компоненты. Эффективные классы, такие как POLYGON и ELLIPSE, должны обеспечить реализацию отложенных компонентов display, rotate.

Для удобства мы будем называть тип отложенным, если его базовый класс является отложенным. Таким образом, класс FIGURE, рассматриваемый как тип, является отложенным. Если родовой класс LIST является отложенным (как это и должно быть, если он представляет понятие списка, не зависящее от реализации), то тип LIST [INTEGER] является отложенным. Учитывается только базовый класс: C [X] будет эффективным, если класс C эффективный, и отложенным, если C является отложенным, независимо от статуса X.

<p>Соглашения о графических обозначениях</p>

Сейчас можно полностью объяснить графические символы, использованные на рис. 14.8. Звездочкой отмечаются отложенные компоненты или классы:

FIGURE*

display*

perimeter* -- На уровне класса OPEN_FIGURE на рис. 14.8

Перейти на страницу:

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