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

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), является абстрактной подпрограммой. Если это примитивная подпрограмма помеченного типа, то помеченный тип должен быть абстрактным.
Если у типа есть неявная примитивная подпрограмма, которая наследуется или является предопределённым оператором, и соответствующая примитивная подпрограмма родительского или предкового типа является абстрактной или является функцией с результатом типа доступа, контролирующим доступ, или если тип, отличный от неабстрактного нулевого расширения, наследует функцию с результатом, контролирующим доступ, то:
  • Если тип абстрактный или неименованный, то неявная подпрограмма является абстрактной.
  • В противном случае подпрограмма должна быть переопределена неабстрактной подпрограммой или, в случае частного расширения, наследующего неабстрактную функцию с результатом, контролирующим доступ, должна иметь полный тип, который является нулевым расширением; для типа, объявленного во видимой части пакета, переопределение может быть в видимой или частной части. Такая подпрограмма называется требующей переопределения. Однако, если тип является формальным типом обобщения, подпрограмма не должна быть переопределена для самого формального типа; неабстрактная версия будет обязательно предоставлена фактическим типом.
Вызов абстрактной подпрограммы должен быть вызовом диспетчеризации; недиспетчеризованные вызовы абстрактной подпрограммы недопустимы.
Тип агрегата aggregate, или объекта, созданного с помощью object_declaration или allocator, или формального обобщенного объекта режима in не должен быть абстрактным. Тип цели операции присваивания (см. 5.2) не должен быть абстрактным. Тип компонента не должен быть абстрактным. Если тип результата функции абстрактный, то функция должна быть абстрактной. Если функция имеет результат доступа, обозначающий абстрактный тип, то функция должна быть абстрактной. Тип, обозначенный return_subtype_indication (см. 6.5), не должен быть абстрактным. Обобщенная функция не должна иметь абстрактный тип результата или тип результата доступа, обозначающий абстрактный тип.
Если частичный вид не является абстрактным, соответствующий полный вид не должен быть абстрактным. Если формальный обобщенный тип является абстрактным, то для каждой примитивной подпрограммы формального типа, которая не является абстрактной, соответствующая примитивная подпрограмма фактического типа не должна быть абстрактной.
Для абстрактного типа, объявленного в видимой части, абстрактная примитивная подпрограмма не должна быть объявлена в частной части, за исключением случаев, когда она переопределяет абстрактную подпрограмму, неявно объявленную в видимой части. Для помеченного типа, объявленного в видимой части, примитивная функция с результатом, контролирующим доступ, или результат доступа, контролирующий доступ, не должна быть объявлена в частной части, за исключением случаев, когда она переопределяет функцию, неявно объявленную в видимой части.
Фактическая обобщенная подпрограмма не должна быть абстрактной подпрограммой, если только формальная обобщенная подпрограмма не объявлена с помощью formal_abstract_subprogram_declaration. prefix ссылки на атрибут attribute_reference для атрибутов Access, Unchecked_Access или Address не должен обозначать абстрактную подпрограмму.

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

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

Примеры

Пример абстрактного типа, представляющего множество натуральных чисел:
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;
ПРИМЕЧАНИЯ
84 Примечания к примеру: Учитывая приведенный выше абстрактный тип, можно затем вывести различные (неабстрактные) расширения типа, представляющие альтернативные реализации множества. Можно использовать битовый вектор, но установить верхнюю границу наибольшего представимого элемента, а другой может использовать хеш-таблицу, обменивая пространство на гибкость.


Spec-Zone.ru

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