Ада-95. Компилятор GNAT

       

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


В большинстве случаев, типы которые разрабатываются как родоначальники иерархий производных типов не предназначены для непосредственного описания объектов (переменных).

Такие типы называют абстрактными, а для их описания используется зарезервированное слово abstract.

Например:

type Empty_Root is abstract tagged null record;

type Simple_Root is abstract tagged

record

Simple_Field: Integer; end record;

Здесь, в первом случае, тип Empty_Root - это абстрактный тип является "пустой" записью которая не содержит никаких полей. В свою очередь, тип Simple_Root, который также описан как абстрактный, содержит единственное поле Simple_Field типа Integer.

Абстрактный тип может иметь абстрактные подпрограммы.

Абстрактными называют подпрограммы которые фактически не имеют тела (то есть реализации), а это значит, что они обязательно должны быть переопределены в производных типах.

Смысл использования описания абстрактного типа с абстрактными подпрограммами заключается в том, что все производные типы, в последствии, будут вынуждены поддерживать общую логическую функциональность.

Описание абстрактного типа имеющего абстрактные подпрограммы может иметь следующий вид:

package Sets is

type Set is abstract tagged null record;

function Empty return Set is abstract; function Empty(Element : Set) return Boolean is abstract; function Union(Left, Right : Set) return Set is abstract; function Intersection(Left, Right : Set) return Set is abstract; procedure Insert(Element : Natural; Into : Set) is abstract; end Sets;

Это описание множества натуральных чисел взято из справочного руководства по языку Ада.

Примечательно то, что компиляор не позволит описать переменную типа Set, поскольку тип Set - это абстрактный тип.

Таким образом, следующий пример не будет компилироваться:

with Sets; use Sets;

procedure Wont_Compile is

My_Set : Set; -- НЕДОПУСТИМО!!! абстрактный тип

begin null; end Wont_Compile;

Как правило, тип, производный от абстрактного, обеспечивает реализацию функциональности которая была задана в абстрактном типе предке.




Например:

with Sets;

package Quick_Sets is

type Bit_Vector is array(0..255) of Boolean; pragma Pack (Bit_Vector);

type Quick_Set is new Sets.Set with

record

Bits : Bit_Vector := (others => False); end record;

-- объявление конкретной реализации function Empty return Quick_Set; function Empty(Element : Quick_Set) return Boolean;

. . .

Показанный выше схематический пример описывает тип Quick_Set, производный от абстрактного типа Set.

В этом примере, тип Quick_Set осуществляет реализацию функциональности которая была задана в абстрактном типе Set.

В результате, после описания типа Quick_Set, мы можем описывать и использовать объекты типа Quick_Set

логическая функциональность которых будет соответствовать функциональности абстрактного типа Set.

Необходимо также заметить, что Ада позволяет чтобы вновь описываемый тип, производный от абстрактного типа, также был абстрактным.

Используя такие возможности можно разработать иерархию абстрактных типов, которая будет определять логическую функциональность программной подсистемы или всего программного проекта.


Содержание раздела