Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

3.9.3 Абстрактные типы и подпрограммы

Абстрактный тип — это помеченный тип, предназначенный для использования в качестве предка других типов, но не допускающий создания собственных объектов. Абстрактная подпрограмма — это подпрограмма без тела, которая должна быть переопределена при наследовании. Поскольку объекты абстрактного типа создать нельзя, вызов подпрограммы с диспетчеризацией всегда выполняется с использованием переопределённого тела.

Синтаксис

abstract_subprogram_declaration ::=
[overriding_indicator]
subprogram_specification is abstract
[aspect_specification];

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

Типы интерфейсов (см. 3.9.4) являются абстрактными типами. Кроме того, помеченный тип, в объявлении которого используется зарезервированное слово abstract, является абстрактным типом. Классовый тип (см. 3.4.1), укоренённый в абстрактном типе, сам по себе не является абстрактным типом.

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

Только помеченный тип может иметь зарезервированное слово abstract в своём объявлении.
Подпрограмма, объявленная с помощью abstract_subprogram_declaration или formal_abstract_subprogram_declaration (см. 12.6), является абстрактной подпрограммой. Если это примитивная подпрограмма помеченного типа, то помеченный тип должен быть абстрактным.
Если у типа есть неявная примитивная подпрограмма, которая унаследована или является предопределённым оператором, и соответствующая примитивная подпрограмма родительского или предкового типа является абстрактной или является функцией с результатом-доступом, контролируемым или если тип, отличный от неабстрактного нулевого расширения, унаследовал функцию с контролируемым результатом, то:
  • Если тип является абстрактным или неименованным, неявная подпрограмма является абстрактной.
  • В противном случае подпрограмма должна быть переопределена неабстрактной подпрограммой или, в случае частного расширения, наследующего неабстрактную функцию с контролируемым результатом, должна иметь полный тип, который является нулевым расширением; для типа, объявленного в видимой части пакета, переопределение может быть как в видимой, так и в скрытой части. Такая подпрограмма называется требующей переопределения. Однако, если тип является формальным типом обобщения, подпрограмма может быть унаследована как есть, без переопределения для формального типа; неабстрактная версия обязательно будет предоставлена фактическим типом.
Вызов абстрактной подпрограммы должен быть вызовом с диспетчеризацией; вызовы без диспетчеризации к абстрактной подпрограмме запрещены. В дополнение к местам, где обычно применяются Правила легальности (см. 12.3), эти правила также применяются в скрытой части экземпляра обобщенного блока.
Если имя или префикс, указанные в iterator_procedure_call (см. 5.5.3), обозначает абстрактную подпрограмму, подпрограмма должна быть подпрограммой с диспетчеризацией.
Тип агрегата, объекта, созданного с помощью object_declaration или allocator, или формального объекта обобщения в режиме in не должен быть абстрактным. Тип целевого объекта операции присваивания (см. 5.2) не должен быть абстрактным. Тип компонента не должен быть абстрактным. Если тип результата функции является абстрактным, то функция должна быть абстрактной. Если функция имеет тип результата-доступ, указывающий на абстрактный тип, то функция должна быть абстрактной. Тип, обозначаемый return_subtype_indication (см. 6.5), не должен быть абстрактным. Функция обобщения не должна иметь абстрактный тип результата или тип результата-доступ, указывающий на абстрактный тип.
Если частичный вид не абстрактный, соответствующий полный вид не должен быть абстрактным. Если формальный тип обобщения является абстрактным, то для каждой примитивной подпрограммы формального типа, которая не является абстрактной, соответствующая примитивная подпрограмма фактического типа не должна быть абстрактной.
Для абстрактного типа, объявленного в видимой части, абстрактная примитивная подпрограмма не должна быть объявлена в скрытой части, если только она не переопределяет абстрактную подпрограмму, неявным образом объявленную в видимой части. Для помеченного типа, объявленного в видимой части, примитивная функция с результатом-результатом или результатом-доступом, контролирующим, не должна быть объявлена в скрытой части, если только она не переопределяет функцию, неявным образом объявленную в видимой части.
Фактическая подпрограмма обобщения не должна быть абстрактной подпрограммой, если формальная подпрограмма обобщения не объявлена с помощью formal_abstract_subprogram_declaration. Префикс attribute_reference для атрибутов Access, Unchecked_Access или Address не должен обозначать абстрактную подпрограмму.

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

Выполнение abstract_subprogram_declaration не оказывает никакого влияния.
ПРИМЕЧАНИЕ 1 Абстрактность не наследуется; тип является абстрактным только если зарезервированное слово abstract используется в объявлении расширения типа.
ПРИМЕЧАНИЕ 2 Классовый тип никогда не является абстрактным. Даже если класс укоренён в абстрактном типе, классовый тип для класса не является абстрактным, и объект классового типа может быть создан; метка такого объекта будет идентифицировать какой-то неабстрактный тип в классе.

Примеры

Пример абстрактного типа, представляющего множество натуральных чисел:
package Sets is
subtype Element_Type is Natural;
type Set is abstract tagged null record;
function Empty return Set is abstract;
function Union(Left, Right : Set) return Set is abstract;
function Intersection(Left, Right : Set) return Set is abstract;
function Unit_Set(Element : Element_Type) return Set is abstract;
procedure Take(Element : out Element_Type;
From : in out Set) is abstract;
end Sets;
Учитывая вышеуказанный абстрактный тип, можно получить различные (неабстрактные) расширения типа, представляющие альтернативные реализации множества. Один из вариантов — использовать битовый вектор, но установить верхнюю границу для самого большого представимого элемента, а другая возможная реализация — хеш-таблица, обменивающая память на гибкость.


Spec-Zone.ru

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