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



         

Абстрагирование общей функциональности


Показанные ранее реализации стека, предусматривали общее множество подпрограмм, таких как Push, Pop, и т.д.

В Аде, мы можем установить общность используя общий тип.

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

При этом, он не указывает как реализовать эти подпрограммы.

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

Такой общий тип называют абстрактным типом, и он является абстракцией абстракции.

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

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

Рассмотрим следующий пример:

package Stacks is

type Stack is abstract tagged null record; -- абстрактный тип, который не имеет полей, и не имеет "реальных" операций. -- Ада требует "tagged"-описание для абстрактных типов.

Underflow : exception; Overflow : exception;

procedure Push(Item : in out Stack; Value : in Integer) is abstract; procedure Pop(Item : in out Stack; Value : out Integer) is abstract;

function Full(Item : Stack) return Boolean is abstract; function Empty(Item : Stack) return Boolean is abstract;

function Init return Stack is abstract;

end Stacks;

В данном случае, в пакете Stacks описан абстрактный тип стека Stack.

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

Примечательно, что тип Stack может быть приватным:

package Stacks is

type Stack is abstract tagged private;

-- подпрограммы . . .

private

type Stack is abstract tagged null record;

end Stacks;

В этом же пакете или, что более типично, в другом пакете, можно описать расширение типа Stack и создать производный тип, который реализует указанную функциональность абстрактного типа:

with Lists; with Stacks;

package Unbounded_Stacks is

type Unbounded_Stack is new Stacks.Stack with private; -- тип Unbounded_Stack, производный от пустой записи стек, -- с небольшим расширением, добавленным как описано в приватной -- секции

procedure Push(Item : in out Unbounded_Stack; Value : in Integer); procedure Pop(Item : in out Unbounded_Stack; Value : out Integer);

function Full(Item : Unbounded_Stack) return Boolean; function Empty(Item : Unbounded_Stack) return Boolean;

-- возвращает пустой инициализированный Unbounded_Stack

function Init return Unbounded_Stack;

private

-- Расширяет пустую запись Stacks.Stack на одно поле. -- Все вызовы будут перенаправлены к внутреннему -- связанному списку.

type Unbounded_Stack is new Stacks.Stack with record

Values : Lists.List; end record;

end Unbounded_Stacks;

<


Содержание  Назад  Вперед