Справочник по Ada 2005
7.3 Типы с закрытым представлением и расширения типов с закрытым представлением
Декларация (в видимой части пакета) типа как типа с закрытым представлением или расширения типа с закрытым представлением служит для разделения характеристик, которые могут быть использованы непосредственно внешними программными модулями (то есть, логические свойства), от других характеристик, прямое использование которых ограничено пакетом (детали определения самого типа). См. 3.9.1 для обзора расширений типов.
Синтаксис
private_type_declaration ::=
type defining_identifier [discriminant_part] is [[abstract] tagged] [limited] private;
type defining_identifier [discriminant_part] is [[abstract] tagged] [limited] private;
private_extension_declaration ::=
type defining_identifier [discriminant_part] is
[abstract] [limited | synchronized] new ancestor_subtype_indication
[and interface_list] with private;
type defining_identifier [discriminant_part] is
[abstract] [limited | synchronized] new ancestor_subtype_indication
[and interface_list] with private;
Правила легальности
private_type_declaration или private_extension_declaration объявляют частичный вид типа; такая декларация допускается только как declarative_item видимой части пакета, и она требует завершения, которое должно быть full_type_declaration, являющимся declarative_item закрытой части пакета. Вид типа, объявленный full_type_declaration, называется полным видом. Генерический формальный тип с закрытым представлением или генерическое формальное расширение типа с закрытым представлением также являются частичными видами.
Тип должен быть полностью определён перед его заморозкой (см. 3.11.1 и 13.14). Таким образом, ни объявление переменной частичного вида типа, ни создание с помощью allocator объекта частичного вида не допускаются до полного объявления типа. Аналогично, до полного объявления имя частичного вида не может использоваться в generic_instantiation или в элементе представления.
Тип с закрытым представлением является ограниченным, если его объявление включает ключевое слово limited; расширение типа с закрытым представлением является ограниченным, если его тип-предок является ограниченным типом, который не является типом-интерфейсом, или если ключевое слово limited или synchronized встречается в его определении. Если частичный вид неограниченный, то полный вид должен быть неограниченным. Если частичный вид помеченный (tagged) является ограниченным, то полный вид должен быть ограниченным. С другой стороны, если частичный вид непомеченный (untagged) является ограниченным, то полный вид может быть ограниченным или неограниченным.
Если частичный вид помечен (tagged), то полный вид должен быть помеченным. С другой стороны, если частичный вид непомечен (untagged), то полный вид может быть помеченным или непомеченным. В случае, когда частичный вид непомечен (untagged), а полный вид помечен (tagged), производные от частичного вида не допускаются в пределах непосредственной области видимости частичного вида; производные от полного вида допускаются.
Если полный тип имеет частичный вид, который помечен (tagged), то:
- частичный вид должен быть синхронизированным помеченным типом (см. 3.9.4), если и только если полный тип является синхронизированным помеченным типом;
- частичный вид должен быть потомком типа-интерфейса (см. 3.9.4), если и только если полный тип является потомком типа-интерфейса.
Тип-предок private_extension_declaration — это тип, определённый ancestor_subtype_indication; тип-предок должен быть конкретным помеченным типом. Полный вид расширения типа с закрытым представлением должен быть получен (прямо или косвенно) от типа-предка. В дополнение к местам, где обычно применяются правила легальности (см. 12.3), требование, чтобы предок был конкретным, применяется также в закрытой части экземпляра генерируемого модуля.
Если ключевое слово limited появляется в private_extension_declaration, то тип-предок должен быть ограниченным типом. Если ключевое слово synchronized появляется в private_extension_declaration, то тип-предок должен быть ограниченным интерфейсом.
Если объявление частичного вида включает known_discriminant_part, то full_type_declaration должен иметь полностью соответствующую (явную) known_discriminant_part (см. 6.3.1, «Правила соответствия»). Тип-предок может быть неограниченным; тип-родитель полного вида должен быть ограниченным (см. 3.7).
Если расширение типа с закрытым представлением наследует известные дискриминанты от типа-предка, то полный вид также должен наследовать свои дискриминанты от типа-предка, и тип-родитель полного вида должен быть ограниченным тогда и только тогда, когда тип-предок ограничен.
Если full_type_declaration для расширения типа с закрытым представлением определён с помощью derived_type_definition, то ключевое слово limited должно присутствовать в full_type_declaration тогда и только тогда, когда оно также присутствует в private_extension_declaration.
Если у частичного вида неизвестные дискриминанты, то full_type_declaration может определять определённый или неопределённый тип с или без дискриминантов.
Если у частичного вида нет ни известных, ни неизвестных дискриминантов, то full_type_declaration должен определить определённый тип.
Если тип-предок расширения типа с закрытым представлением имеет ограниченные дискриминанты, то тип-родитель полного вида должен наложить статически соответствующее ограничение на эти дискриминанты.
Статическая семантика
private_type_declaration объявляет тип с закрытым представлением и его первый тип-подтип. Аналогично, private_extension_declaration объявляет расширение типа с закрытым представлением и его первый тип-подтип.
Объявление частичного вида и соответствующий full_type_declaration определяют два вида одного типа. Объявление частичного вида вместе с видимой частью определяют операции, доступные внешним программным модулям; объявление полного вида вместе с закрытой частью определяют другие операции, чьё прямое использование возможно только в области видимости самого пакета. Более того, в рамках области видимости объявления полного вида, характеристики типа определяются полным видом; в частности, в пределах его области видимости, полный вид определяет классы, включающие тип, какие компоненты, записи, и защищённые подпрограммы видимы, какие атрибуты и другие предопределённые операции разрешены, и является ли первый тип-подтип статическим. См. 7.3.1.
Расширение типа с закрытым представлением наследует компоненты (включая дискриминанты, если не указан новый discriminant_part) и определённые пользователем примитивные подпрограммы из типа-предка и типов-предков (если таковые имеются), аналогично тому, как расширение записи наследует компоненты и определённые пользователем примитивные подпрограммы из родительского типа и типов-предков (см. 3.4).
Динамическая семантика
Выполнение private_type_declaration создаёт частичный вид типа. Выполнение private_extension_declaration выполняет ancestor_subtype_indication и создаёт частичный вид типа.
ПРИМЕЧАНИЯ
5 Частичный вид типа, как он объявлен private_type_declaration, определён как составной вид (в 3.2). Полный вид типа может или не может быть составным. Расширение типа с закрытым представлением также составное, как и его полный вид.
6 Объявление типа с закрытым представлением с unknown_discriminant_part — это способ предотвращения создания клиентами неинициализированных объектов типа; тогда они вынуждены инициализировать каждый объект, вызывая какую-либо операцию, объявленную в видимой части пакета.
END_OF_DOCUMENT_MARKER 7 Тип предка, указанный в private_extension_declaration, и тип родителя, указанный в соответствующем объявлении расширения записи, заданном в закрытой части, не обязательно должны быть одинаковыми. Если тип предка не является типом интерфейса, тип родителя полного представления может быть любым потомком типа предка. В этом случае для примитивного подпрограммы, унаследованного от типа предка и не переопределённого, имена формальных параметров и выражения по умолчанию (если таковые имеются) берутся из соответствующего примитивного подпрограммы указанного типа предка, а тело берётся из соответствующего примитивного подпрограммы типа родителя полного представления. См. 3.9.2.
8 Если тип предка, указанный в private_extension_declaration, является типом интерфейса, тип родителя может быть любым типом, при условии, что полное представление является потомком типа предка. Типы предков, указанные в private_extension_declaration, и типы предков, указанные в соответствующем объявлении расширения записи, заданном в закрытой части, не обязательно должны быть одинаковыми — единственное требование состоит в том, чтобы закрытое расширение и расширение записи произошли от одного и того же набора интерфейсов.
Примеры
Примеры объявлений закрытых типов:
type Ключ is private;
type Имя_файла is limited private;
type Имя_файла is limited private;
Пример объявления закрытого расширения:
type Список is new Ada.Finalization.Controlled with private;