Развернутые типы


Ссылок не достаточно

 

До сих пор все значения целочисленных, булевых и других аналогичных типов рассматривались как ссылки на объекты. Однако по двум причинам необходимы сущности, значениями которых являются объекты:

[x]. В предыдущей лекции была поставлена важная цель - построение полностью унифицированной системы типов. В этой схеме базовые типы (BOOLEAN , INTEGER и др.) обрабатываются аналогично типам, введенным разработчиком (POINT , BOOK и др.). Тем не менее, если используется сущность n типа INTEGER , то в большинстве случаев удобнее полагать, что значение n - целое число, а не ссылка на объект содержащий целое число. Это удобнее отчасти по соображениям эффективности. Понятно, что для размещения целочисленных объектов необходимо больше памяти, а на обработку косвенного доступа к ним - дополнительное время. Кроме того, концептуально целое число и ссылка на целое число - совершенно различные понятия. Этот довод важен, если нашей целью является построение точной модели.

[x]. Даже в случае сложных, определенных программистом объектов, может оказаться предпочтительным включение в объект O1 подобъекта O2 , а не ссылки на внешний объект O2 . Причиной такого подхода могут быть повышение эффективности, точное моделирование или и то, и другое.

 

 

Удовлетворить потребность в составных объектах очень просто. Пусть C - класс, определенный так, как это делалось до сих пор

 

class C feature

...

end

 

Класс C может использоваться в качестве типа. Любая сущность типа C является ссылкой. По этой причине C называется ссылочным типом (reference type) .

Теперь предположим, что нам необходима сущность x , значение которой во время выполнения будет экземпляром C , а не ссылкой на такой экземпляр. Это достигается следующим объявлением x :

 

x : expanded C

 

Эта нотация использует новое ключевое слово expanded (развернутый) . Нотация expandedC означает, что экземпляры этого типа в точности соответствуют экземплярам C . Единственное отличие от обычного объявления типа состоит в том, что сущности типа C обозначают ссылки, которые могут быть присоединены к экземплярам C , а сущности типа expandedC обозначают непосредственно экземпляры C .

Таким образом, к структуре, определенной в предыдущих разделах, добавлено понятие составного объекта (composite object) . Объект O называется составным, если одно или более его полей являются объектами - подобъектами (subobjects)O . Следующий класс является примером описания составных объектов:

 

class COMPOSITE feature

ref: C

sub: expanded C

end

 

Класс COMPOSITE имеет два атрибута: ref , обозначающий ссылку, и sub , обозначающий подобъект. Вот как выглядит прямой экземпляр COMPOSITE .

Рис. 8.19. Составной объект с одним подобъектом

Поле ref является ссылкой, присоединенной к экземпляру C (возможно, пустой ссылкой). Поле sub содержит экземпляр C и не может быть пустым.

Удобно несколько расширить нотацию. Иногда при проектировании класса, например E , хотелось бы установить, что все экземпляры класса должны быть развернутыми. Чтобы сделать это требование явным, следует объявить класс в следующей форме:

 

expanded class E feature

... Далее все аналогично любому другому классу ...

end

 

Так определенный класс называется развернутым классом. Такое объявление класса никак не отражается на экземплярах класса, они остаются такими же, как если бы класс был объявлен просто class E . Но сущности типа E изменяются - теперь их значения не ссылки, а сами объекты. Как следствие этой новой возможности понятие развернутого типа включает два случая:

Определение: развернутый тип

Тип является развернутым в двух случаях:

Он задан в форме: expandedC

Он задан в форме E , где E - развернутый класс.

Объявление вида

 

x: expanded E

 

где E - развернутый класс, не будет ошибкой, поскольку эквивалентно

 

x: E

 

Таким образом, имеется два вида типов. Тип, не являющийся развернутым, является ссылочным типом. Эту терминологию можно использовать и для сущностей - ссылочные сущности и развернутые сущности. Аналогично и классы могут быть ссылочными и развернутыми.