Справочник по Ada 2012
7.3 Типы с приватной частью и расширения типов с приватной частью
Объявление (в видимой части пакета) типа как типа с приватной частью или расширения типа с приватной частью служит для разделения характеристик, которые могут быть использованы непосредственно внешними блоками программы (то есть логические свойства), от других характеристик, непосредственное использование которых ограничено пакетом (детали определения самого типа). См. 3.9.1 для обзора расширений типов.
Синтаксис
private_type_declaration ::=
type defining_identifier [discriminant_part] is [[abstract] tagged] [limited] private
[aspect_specification];
type defining_identifier [discriminant_part] is [[abstract] tagged] [limited] private
[aspect_specification];
private_extension_declaration ::=
type defining_identifier [discriminant_part] is
[abstract] [limited | synchronized] new ancestor_subtype_indication
[and interface_list] with private
[aspect_specification];
type defining_identifier [discriminant_part] is
[abstract] [limited | synchronized] new ancestor_subtype_indication
[and interface_list] with private
[aspect_specification];
Правила легальности
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 появляется в его определении. Если частичный вид является неограниченным, то полный вид должен быть неограниченным. Если частичный вид типа с метками является ограниченным, то полный вид должен быть ограниченным. С другой стороны, если частичный вид без меток является ограниченным, полный вид может быть ограниченным или неограниченным.
Если частичный вид имеет метки, то полный вид должен иметь метки. С другой стороны, если частичный вид не имеет меток, то полный вид может иметь или не иметь меток. В случае, когда частичный вид не имеет меток, а полный вид имеет метки, производные от частичного вида не допускаются в пределах непосредственной области видимости частичного вида; производные от полного вида разрешены.
Если полный тип имеет частичный вид с метками, то:
- частичный вид должен быть синхронизированным типом с метками (см. 3.9.4), если и только если полный тип является синхронизированным типом с метками;
- частичный вид должен быть потомком типа-интерфейса (см. 3.9.4), если и только если полный тип является потомком типа-интерфейса.
Тип-предок private_extension_declaration — это подтип, определенный subtype_indication; тип-предок должен быть конкретным типом с метками. Полный вид расширения типа должен быть производным (прямо или косвенно) от типа-предка. Помимо мест, где обычно применяются правила легальности (см. 12.3), требование, чтобы предок был конкретным, применяется также в приватной части экземпляра обобщенного блока.
Если в private_extension_declaration появляется зарезервированное слово limited, тип-предок должен быть ограниченным типом. Если в private_extension_declaration появляется зарезервированное слово synchronized, тип-предок должен быть ограниченным типом-интерфейсом.
Если объявление частичного вида включает 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 определяют два вида одного типа. Объявление частичного вида вместе с видимой частью определяет операции, доступные внешним блокам программы; объявление полного вида вместе с приватной частью определяет другие операции, непосредственное использование которых возможно только в пределах области объявления самого пакета. Более того, в области видимости объявления полного вида характеристики (см. 3.4) типа определяются полным видом; в частности, в его области видимости полный вид определяет классы, которые включают тип, какие компоненты, записи и защищенные подпрограммы являются видимыми, какие атрибуты и другие предопределенные операции разрешены, и является ли первый подтип статическим. См. 7.3.1.
Для расширения типа характеристики (включая компоненты, но исключая дискриминанты, если указан новый discriminant_part), предопределенные операторы и унаследованные пользовательские примитивные подпрограммы определяются типом-предком и типами-прогенеторами (если таковые имеются), точно так же, как это определяется для расширения записи типом-родителя и типами-прогенеторами (см. 3.4 и 7.3.1).
Динамическая семантика
Выполнение private_type_declaration создает частичный вид типа. Выполнение private_extension_declaration выполняет subtype_indication и создает частичный вид типа.
ПРИМЕЧАНИЯ
5 Частичный вид типа, объявленный с помощью private_type_declaration, определяется как составной вид (в 3.2). Полный вид типа может или не может быть составным. Расширение типа также является составным, как и его полный вид.
END_OF_DOCUMENT_MARKER 6 Объявление приватного типа с unknown_discriminant_part — способ предотвращения создания клиентами неинициализированных объектов типа; объекты затем должны быть инициализированы вызовом операции, объявленной в видимой части пакета.
7 Тип предка, указанный в private_extension_declaration, и тип родителя, указанный в соответствующем объявлении расширения записи в приватной части, могут не совпадать. Если тип предка не является типом интерфейса, то тип родителя полного представления может быть любым потомком типа предка. В этом случае для примитивного подпрограммы, унаследованного от типа предка и не переопределённого, имена формальных параметров и (при наличии) выражения по умолчанию берутся из соответствующего примитивного подпрограммы указанного типа предка, а тело — из соответствующего примитивного подпрограммы типа родителя полного представления. См. 3.9.2.
8 Если тип предка, указанный в private_extension_declaration, является типом интерфейса, тип родителя может быть любым типом, при условии, что полное представление является потомком типа предка. Типы-предшественники, указанные в private_extension_declaration, и типы-предшественники, указанные в соответствующем объявлении расширения записи в приватной части, могут не совпадать — единственное требование состоит в том, чтобы приватное расширение и расширение записи происходили от одного и того же набора интерфейсов.
Примеры
Примеры объявлений приватных типов:
type Key is private;
type File_Name is limited private;
type File_Name is limited private;
Пример объявления приватного расширения:
type List is new Ada.Finalization.Controlled with private;