Все типы, производные и расширенные (прямо или косвенно) от определенного тэгового типа T, принадлежат одному иерархическому образованию класса, корнем которого будет тэговый тип T.
Тэговый тип T неявно ассоциирован с надклассовым типом который обозначает целый класс типов - иерархию включающую данный тэговый тип T
и все производные от него типы.
Надклассовый тип не имеет явного имени и обозначается как атрибут T'Class, где T - имя соответствующего тэгового типа.
В таком контексте, явно описанные типы удобно называть индивидуальными типами, чтобы подчеркнуть их отличие от надклассовых типов.
В иерархическом образовании класса каждый индивидуальный тип идентифицируется тэгом (tag), который скрыто присутствует в каждом тэговом типе (отсюда, собственно, и название "тэговые" типы).
Наличие такой информации позволяет осуществлять идентификацию индивидуального типа объекта во время выполнения программы (то есть, динамически) и, используя результат такой идентификации, находить для этого объекта соответствующую реализацию операций.
Следует также заметить, что такой подход является некоторым ослаблением традиционной модели строгой типизации Ады, поскольку любой тип, производный от типа T, может быть неявно преобразован в надклассовый тип T'Class.
Для демонстрации сказанного, предположим, что у нас имеется следующая иерархия типов:
| Root | ----------------- | | Child_1 Child_2 | | | Grand_Child_2_1 |
Предположим также, что спецификация пакета, описывающего показанную выше иерархию типов, имеет следующий вид (заметим, что пустые записи и расширения использованы для упрощения примера):
| package Simple_Objects is
-- тип Root и его примитивные операции type Root is tagged null record; function The_Name (Self: in Root) return String; procedure Show (Self: in Root'Class); -- тип Child_1 и его примитивные операции type Child_1 is new Root with null record; function The_Name (Self: in Child_1) return String; -- тип Child_2 и его примитивные операции type Child_2 is new Root with null record; function The_Name (Self: in Child_2) return String; -- тип Grand_Child_2_1 и его примитивные операции type Grand_Child_2_1 is new Child_2 with null record; function The_Name (Self: in Grand_Child_2_1) return String; end Simple_Objects; |
|
V : T'Class := значение_инициализации ; |
|
Instance : Root'Class := Child_1'(Root with null record); |
|
procedure Show (Self : in Root'Class); |
|
declare Root_Instance : Root; Child_1_Instance : Child_1; Child_2_Instance : Child_2; GRand_Child_2_1_Instance : GRand_Child_2_1; Instance : Root'Class := Child_1'(Root with null record); begin Show (Root_Instance); Show (Child_1_Instance); Show (Child_2_Instance); Show (GRand_Child_2_1_Instance); Show (Instance); end; |
|
type Root_Ref is access Root'Class; |
|
declare Any_Instance: Root_Ref; begin Any_Instance := new Child_1'(Root with null record); . . . Any_Instance := new Child_2'(Root with null record); . . . end; |