Справочник по Ada 2005
3.9.1 Расширения типов
Каждый тип расширения является помеченным типом и представляет собой расширение записи или частное расширение некоторого другого помеченного типа, или неинтерфейсный синхронизированный помеченный тип..
Синтаксис
Правила легальности
Родительский тип расширения записи не должен быть типом класса, а также не должен быть синхронизированным помеченным типом (см. 3.9.4). Если родительский тип или любой предшественник не ограничены, то каждый из компонентов record_extension_part должен быть неограниченным. В дополнение к местам, где обычно применяются правила легальности (см. 12.3), эти правила применяются также в частной части экземпляра генерируемого блока.
Внутри тела генерируемого блока или тела любого его дочернего блока библиотечных модулей помеченный тип не должен объявляться как потомок формального типа, объявленного в формальной части генерируемого блока.
Статическая семантика
Расширение записи является нулевым расширением, если в его объявлении нет known_discriminant_part и его record_extension_part не содержит component_declarationов.
Динамическая семантика
Выполнение record_extension_part состоит из выполнения record_definition.
ПРИМЕЧАНИЯ
68 Термин «расширение типа» относится к типу в целом. Термин «часть расширения» относится к фрагменту текста, который определяет дополнительные компоненты (если таковые имеются) расширения типа относительно указанного типа предка.
69 Когда расширение объявляется непосредственно внутри тела, примитивные подпрограммы наследуются и могут быть переопределены, но новые примитивные подпрограммы добавить нельзя.
70 Имя, обозначающее компонент (включая дискриминант) родительского типа, не разрешено в record_extension_part. Аналогично, имя, обозначающее компонент, определённый в record_extension_part, не разрешено в record_extension_part. Разрешено использовать имя, обозначающее дискриминант расширения записи, при условии, что существует новый known_discriminant_part в объявляемом типе. (Полное правило приведено в 3.8.)
71 Каждый видимый компонент расширения записи должен иметь уникальное имя, независимо от того, унаследован ли компонент (видимо) от родительского типа или объявлен в record_extension_part (см. 8.3).
Примеры
Примеры расширений записей (типов, определённых выше в 3.9):
type Painted_Point is new Point with
record
Paint : Color := White;
end record;
-- Компоненты X и Y унаследованы
record
Paint : Color := White;
end record;
-- Компоненты X и Y унаследованы
Origin : constant Painted_Point := (X | Y => 0.0, Paint => Black);
type Literal is new Expression with
record -- лист в дереве Expression
Value : Real;
end record;
record -- лист в дереве Expression
Value : Real;
end record;
type Expr_Ptr is access all Expression'Class;
-- см. 3.10
-- см. 3.10
type Binary_Operation is new Expression with
record -- внутренний узел в дереве Expression
Left, Right : Expr_Ptr;
end record;
record -- внутренний узел в дереве Expression
Left, Right : Expr_Ptr;
end record;
type Addition is new Binary_Operation with null record;
type Subtraction is new Binary_Operation with null record;
-- Для этих расширений дополнительные компоненты не нужны
type Subtraction is new Binary_Operation with null record;
-- Для этих расширений дополнительные компоненты не нужны
Tree : Expr_Ptr := -- Дерево, представляющее «5.0 + (13.0–7.0)»
new Addition'(
Left => new Literal'(Value => 5.0),
Right => new Subtraction'(
Left => new Literal'(Value => 13.0),
Right => new Literal'(Value => 7.0)));
new Addition'(
Left => new Literal'(Value => 5.0),
Right => new Subtraction'(
Left => new Literal'(Value => 13.0),
Right => new Literal'(Value => 7.0)));