Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по основам ООП.docx
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
5.29 Mб
Скачать

Опорный элемент Current

В качестве опорного элемента можно использовать Current , обозначающий текущий экземпляр класса (о текущем экземпляре см. лекцию 7). Сущность, описанная в классе A как like Current , будет считаться в нем имеющей тип A , а в любом B , порожденном от A , - имеющей тип B .

Эта форма закрепленного объявления помогает решить оставшиеся проблемы. Исправим объявление conjugate , получив правильный тип результата функции класса POINT :

conjugate: like Current is

... Все остальное - в точности, как раньше ...

Теперь в каждом порожденном классе тип результата conjugate автоматически определяется заново. Так, в классе PARTICLE он меняется на класс PARTICLE .

В классе LINKABLE , найдя объявления

right: LINKABLE [G]

put_right (other: LINKABLE [G]) is...

замените LINKABLE [G] на like Current . Компонент left класса BI_LINKABLE объявите аналогично.

Эта схема применима ко многим процедурам set_attribute . В классе DEVICE имеем:

class DEVICE feature

alternate: like Current

set_alternate (a: like Current) is

-- Пусть a - альтернативное устройство.

do

alternate := a

end

... Прочие компоненты ...

end

Еще раз о базовых классах

С введением закрепленных типов нуждается в расширении понятие базового класса типа.

Сначала классы и типы были для нас едины, и это их свойство - отправной пункт ОО-метода, - по существу , сохраняется, хотя нам пришлось немного расширить систему типов, добавляя в классы родовые параметры. Каждый тип основан на классе и для типа определено понятие базового класса. Для типов, порожденных универсальным классом с заданными фактическими родовыми параметрами, базовым классом является универсальный класс, в котором удалены фактические параметры. Так, например, для LIST [INTEGER] базовым классом является LIST . На классах основаны и развернутые типы; и для них аналогично: для expanded SOME_CLASS [...] базовый класс - SOME_CLASS .

Закрепление типов - это еще одно расширение системы типов, которое, подобно двум предыдущим, сохраняет свойство выводимости каждого типа непосредственно из класса. Базовым для like anchor является базовый класс типа сущности anchor в текущем классе. Если anchor есть Current , базовым будет класс, в котором это объявление содержится.

Правила о закрепленных типах

Теоретически ничто не мешает нам записать like anchor для самого элемента anchor как сущности закрепленного типа. Достаточно ввести правило, которое запрещало бы циклы в декларативных цепочках.

Вначале закрепленные опорные элементы (anchored anchor) были запрещены, но это новое, более либеральное правило придает системе типов большую гибкость.Пусть T - тип anchor (текущий класс, если anchor есть Current ). Тогда тип like anchor совместим как с самим собой, так и с T .

Обратное определение не симметрично: единственный тип, совместимый с like anchor , - это он сам. В частности, с ним не совместим тип T . Если бы следующий код был верен:

anchor, other: T; x: like anchor

...

create other

x := other -- предупреждение: ошибочное присваивание

то в порожденном классе, где anchor меняет свой тип на U , совместимый с T , но основанный на его потомке, сущности x был бы присвоен объект типа T , а не объект типа U или U -совместимого типа, что некорректно.

Будем говорить, что x опорно-эквивалентен y , если x есть y или имеет тип like z , где z по рекурсии опорно-эквивалентен y . Присваивания: x := anchor , anchor := x , как и присваивания опорно-эквивалентных (anchor-equivalent) элементов, конечно же, допустимы.

При закреплении формального параметра или результата, как в случае

r (other: like Current)

фактический параметр вызова, например, b в a.r(b) , должен быть опорно-эквивалентен a .