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

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

Определение derived_type_definition определяет производный тип (и его первый подтип), характеристики которого производятся от характеристик родительского типа и, возможно, типов-предков.
Класс типов — это множество типов, замкнутое относительно производных; то есть, если родительский тип или тип-предок производного типа принадлежит классу, то и производный тип также принадлежит этому классу. Говоря о том, что определенная группа типов образует класс, мы утверждаем, что все производные типа из этой группы наследуют характеристики, определяющие этот класс. Более общее понятие категории типов используется для множества типов, определяющие характеристики которых не обязательно наследуются производными; например, ограниченные, абстрактные и интерфейсные типы — это категории типов, но не классы типов.

Синтаксис

derived_type_definition ::=
[abstract] [limited] new parent_subtype_indication [[and interface_list] record_extension_part]

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

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

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

Первый подтип производного типа является несопряженным, если в объявлении производного типа присутствует known_discriminant_part или если родительский подтип является несопряженным. В противном случае ограничение первого подтипа соответствует ограничению родительского подтипа в следующем смысле: оно такое же, как у родительского подтипа, за исключением того, что для ограничения диапазона (явного или неявного) значение каждой границы диапазона заменяется соответствующим значением производного типа.
Первый подтип производного типа исключает null (см. 3.10) тогда и только тогда, когда родительский подтип исключает null.
Характеристики производного типа определяются следующим образом:
  • Если родительский тип или тип-предок принадлежит классу типов, то производный тип также принадлежит этому классу. Следующие наборы типов, а также любые наборы более высокого уровня, составленные из них, являются классами в этом смысле, и поэтому характеристики, определяющие эти классы, наследуются производными типами от родительского или предкового типов: целые со знаком, модульные целые, обычные фиксированные, десятичные фиксированные, числа с плавающей точкой, перечисления, булевы, символы, доступ к константам, общий доступ к переменным, доступ к переменным в заданном пуле, доступ к подпрограммам, массивы, строки, составные типы, не массивы, не ограниченные, неупомянутые записи, помеченные, задачи, защищенные и синхронизированные помеченные.
  • Если родительский тип является элементарным типом или массивом, то множество возможных значений производного типа является копией множества возможных значений родительского типа. Для скалярного типа основной диапазон производного типа такой же, как у родительского типа.
  • Если родительский тип — это составной тип, отличный от массива, то компоненты, защищенные подпрограммы и входы, объявленные для производного типа, таковы:
  • Дискриминанты, указанные в новом 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) также выполняет необходимое преобразование типов. Если тип результата унаследованной подпрограммы является производным типом, результат вызова подпрограммы родительского или предкового типа преобразуется в производный тип или, в случае нулевого расширения, расширяется до производного типа с помощью эквивалента extension_aggregate с исходным результатом в качестве ancestor_part и пустого записи в качестве record_component_association_list.
ПРИМЕЧАНИЯ
10 Классы закрыты для производных типов — любой класс, содержащий тип, также содержит его производные. Операции, доступные для данного класса типов, доступны и для производных типов в этом классе.
11 Вычисление унаследованной перечислительной константы эквивалентно вычислению соответствующей перечислительной константы родительского типа, а затем преобразованию результата в производный тип. Это следует из их эквивалентности безпараметрическим функциям.
12 Обобщенная подпрограмма не является подпрограммой и, следовательно, не может быть примитивной подпрограммой и не может быть унаследована производным типом. С другой стороны, экземпляр обобщенной подпрограммы может быть примитивной подпрограммой и, следовательно, может быть унаследован.
13 Если родительский тип является типом доступа, то родительский и производный тип используют один и тот же пул памяти; для производного типа существует нулевое значение доступа, и это является неявным начальным значением для типа. См. 3.10.
14 Если родительский тип — тип Boolean, предопределенные реляционные операторы производного типа возвращают результат предопределенного типа Boolean (см. 4.5.2). Если родительский тип — целочисленный тип, правое операнд предопределенного оператора возведения в степень является предопределенным типом Integer (см. 4.5.6).
15 Любые дискриминанты родительского типа либо все наследуются, либо полностью заменяются новым набором дискриминантов.
16 Для унаследованной подпрограммы подтип формального параметра производного типа не обязательно должен иметь какие-либо общие значения с первым подтипом производного типа.
17 Если ключевое слово abstract указано в объявлении типа, тип является абстрактным (см. 3.9.3).
18 Тип интерфейса, имеющий предковый тип «производный от» этого типа. Однако derived_type_definition никогда не определяет тип интерфейса.
19 Недопустимо, чтобы родительский тип derived_type_definition был синхронизированным помеченным типом.

Примеры

Примеры объявлений производных типов:
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
-- унаследованные подпрограммы имеют следующие спецификации:
-- procedure Get_Key(K : out Special_Key);
-- function "<"(X,Y : Special_Key) return Boolean;


Spec-Zone.ru

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