Spec-Zone.ru › Ada 95
Справочник по Ada 95

3.4 Производные типы и классы

Определение derived_type_definition определяет новый тип (и его первый подтип), характеристики которого производятся от характеристик родительского типа.

Синтаксис

derived_type_definition ::= [абстрактный] новый родительский_subtype_indication [record_extension_part]

Правила легитимности

родительский_subtype_indication определяет родительский подтип; его тип — это родительский тип.
Тип должен быть полностью определен (см. 3.11.1) до того, как он будет указан как родительский тип в derived_type_definition — full_type_declarationы для родительского типа и любых его подкомпонентов должны предшествовать derived_type_definition.
Если есть record_extension_part, производный тип называется расширением записи родительского типа. record_extension_part должен быть предоставлен тогда и только тогда, когда родительский тип является помеченным типом.

Статическая семантика

Первый подтип производного типа является не ограниченным, если в объявлении производного типа предоставлен known_discriminant_part, или если родительский подтип неограничен. В противном случае ограничение первого подтипа соответствует ограничению родительского подтипа в следующем смысле: оно такое же, как и у родительского подтипа, за исключением того, что для ограничения диапазона (явного или неявного) значение каждой границы его диапазона заменяется соответствующим значением производного типа.
Характеристики производного типа определяются следующим образом:
  • Каждый класс типов, включающий родительский тип, также включает производный тип.
  • Если родительский тип является элементарным типом или массивом, то множество возможных значений производного типа является копией множества возможных значений родительского типа. Для скалярного типа базовый диапазон производного типа такой же, как и у родительского типа.
  • Если родительский тип является составным типом, отличным от массива, то компоненты, защищенные подпрограммы и записи, объявленные для производного типа, следуют следующим правилам:
  • Дискриминанты, указанные в новом known_discriminant_part, если он есть; в противном случае каждый дискриминант родительского типа (явным образом объявленный в том же порядке со спецификациями) — в последнем случае дискриминанты называются унаследованными или, если неизвестны в родительском типе, неизвестны и в производном типе;
  • Каждый компонент, запись и защищенная подпрограмма родительского типа, явным образом объявленные в том же порядке с теми же объявлениями; эти компоненты, записи и защищенные подпрограммы называются унаследованными;
  • Каждый компонент, объявленный в record_extension_part, если таковой имеется.
    Объявления компонентов, защищенных подпрограмм и записей, явные или неявные, происходят непосредственно внутри декларативной области типа в указанном выше порядке после родительской subtype_indication.
  • Производный тип ограничен тогда и только тогда, когда родительский тип ограничен.
  • Для каждого предопределенного оператора родительского типа существует соответствующий предопределенный оператор производного типа.
  • Для каждой пользовательской примитивной подпрограммы (кроме пользовательского оператора равенства — см. ниже) родительского типа, уже существующей в месте derived_type_definition, существует соответствующая унаследованная примитивная подпрограмма производного типа с тем же именем. Пользовательские примитивные операторы равенства родительского типа также наследуются производным типом, за исключением случая, когда производный тип является неограниченным расширением записи, и унаследованный оператор имел бы профиль, согласующийся с профилем соответствующего предопределенного оператора равенства; в этом случае пользовательский оператор равенства не наследуется, а скорее включается в реализацию предопределенного оператора равенства расширения записи (см. 4.5.2).
    Профиль унаследованной подпрограммы (включая унаследованную перечислительную константу) получается из профиля соответствующей (пользовательской) примитивной подпрограммы родительского типа после систематической замены каждого подтипа её профиля (см. 6.1), который является родительским типом, соответствующим подтипом производного типа. Для данного подтипа родительского типа соответствующий подтип производного типа определяется следующим образом:
  • Если объявление производного типа не содержит known_discriminant_part и record_extension_part, то соответствующий подтип имеет ограничение, которое соответствует (как определено выше для первого подтипа производного типа) ограничению данного подтипа.
  • Если производный тип является расширением записи, то соответствующий подтип является первым подтипом производного типа.
  • Если производный тип имеет новый known_discriminant_part, но не является расширением записи, то соответствующий подтип ограничен теми значениями, которые при преобразовании в родительский тип принадлежат данному подтипу (см. 4.6).
    Одинаковые формальные параметры имеют default_expressionы в профиле унаследованной подпрограммы. Любой несоответствие типов, вызванное систематической заменой родительского типа производным типом, обрабатывается как часть нормального преобразования типа, связанного с передачей параметров — см. 6.4.1.
Если примитивная подпрограмма родительского типа видна в месте derived_type_definition, то соответствующая унаследованная подпрограмма неявно объявляется сразу после derived_type_definition. В противном случае унаследованная подпрограмма неявно объявляется позже или вообще не объявляется, как описано в 7.3.1.
Производный тип также может быть определен с помощью private_extension_declaration (см. 7.3) или formal_derived_type_definition (см. 12.5.1). Такой производный тип является частичным представлением соответствующего полного или фактического типа.
Все числовые типы являются производными типами, поскольку они неявно производятся от соответствующего корневого числового типа (см. 3.5.4 и 3.5.6).

Динамическая семантика

Выполнение derived_type_definition создаёт производный тип и его первый подтип, и состоит из выполнения subtype_indication и record_extension_part, если таковой имеется. Если subtype_indication зависит от дискриминанта, то вычисляются только те выражения, которые не зависят от дискриминанта.
Для выполнения вызова унаследованной подпрограммы выполняется вызов соответствующей примитивной подпрограммы родительского типа; нормальное преобразование каждого фактического параметра в подтип соответствующего формального параметра (см. 6.4.1) выполняет необходимые преобразования типа. Если тип результата унаследованной подпрограммы — производный тип, результат вызова подпрограммы родительского типа преобразуется в производный тип.
ПРИМЕЧАНИЯ
10 Классы замкнуты относительно производных — любой класс, содержащий тип, также содержит и его производные. Операции, доступные для данного класса типов, доступны и для производных типов в этом классе.
11 Вычисление унаследованной перечислительной константы эквивалентно вычислению соответствующей перечислительной константы родительского типа, а затем преобразованию результата в производный тип. Это следует из их эквивалентности безаргументным функциям.
12 Обобщенная подпрограмма не является подпрограммой и, следовательно, не может быть примитивной подпрограммой и не может быть унаследована производным типом. С другой стороны, экземпляр обобщенной подпрограммы может быть примитивной подпрограммой и, следовательно, может быть унаследован.
13 Если родительский тип является типом доступа, то родительский и производный типы делят один и тот же пул памяти; существует значение доступа null для производного типа, и это является неявным начальным значением для типа. См. 3.10.
14 Если родительский тип — это тип boolean, то предопределенные реляционные операторы производного типа возвращают результат предопределенного типа Boolean (см. 4.5.2). Если родительский тип — это целочисленный тип, то правое операнд предопределенного оператора возведения в степень является предопределенным типом Integer (см. 4.5.6).
15 Любые дискриминанты родительского типа либо полностью наследуются, либо полностью заменяются новым набором дискриминантов.
16 Для унаследованной подпрограммы подтип формального параметра производного типа не обязательно должен иметь какие-либо общие значения с первым подтипом производного типа.
17 Если в объявлении типа указано ключевое слово абстрактный, то тип является абстрактным (см. 3.9.3).

Примеры

Примеры объявлений типов производных:
type Local_Coordinate is new Coordinate; -- два разных типа
type Midweek is new Day range Tue .. Thu; -- см. 3.5.1
type Counter is new Positive; -- тот же диапазон, что и Positive
type Special_Key is new Key_Manager.Key; -- см. 7.3.1
-- унаследованные подпрограммы имеют следующие спецификации:
-- процедура Get_Key(K : out Special_Key);
-- функция "<"(X,Y : Special_Key) return Boolean;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API