"Адское" программирование Ada-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;

В данном случае, для реализации функциональности, которая задана абстрактным типом Stack, необходимо чтобы вызовы подпрограмм, обращенные к типу Unbounded_Stack, были соответствующим образом перенаправлены к связанному списку.Таким образом, тело пакета Unbounded_Stacks будет иметь следующий вид:

package body Unbounded_Stacks is procedure Push(Item : in out Unbounded_Stack; Value : in Integer) is begin Lists.Insert_At_Head(Item.Values, Value); end Push; procedure Pop(Item : in out Unbounded_Stack; Value : out Integer) is begin Lists.Remove_From_Head(Item.Values, Value); exception when Lists.Underflow => raise Stacks.Underflow; end Pop; . . .end Unbounded_Stacks;



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








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