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

       

Смешанное наследование


Смешанное наследование является формой множественного наследования при котором одна или две комбинированных абстракции выступают в роли шаблонов (subpattern).

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

Построение шаблонов может быть выполнено без явного множественного наследования, путем использования одиночного наследования и средств предоставляемых настраиваемыми модулями:

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

Такой смешанный тип (mixin type) может быть использован для специализации общего поведения типа.

Настраиваемый пакет используется как смешанный пакет (mixin package), который инкапсулирует смешанный тип.

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

Смешивание достигается при конкретизации смешанного пакета путем расширения фактического параметра тэгового типа производным абстрактным типом.

При множественном наследовании, производная абстракция установится в обратном направлении иерархии наследования, как тип предок (абстрактный) от которого производится наследование.

Этот способ называют смешанным наследованием (mixin inheritance).

Например, не смотря на множество свойств, которые описывают степень образованности, хорошо известно, что "образованность" сама по себе - не существует.

Подобный шаблон может быть применен по отношению к людям, которые полностью закончили обучение в каком-либо учебном заведении, что и определяет степень (degree) образованности (graduation).

Очевидно, что по отношению к людям, понятие "степень образованности" являться свойством, но самостоятельное использование понятия "степень образованности" - бессмысленно.






Свойства, которые описывают степень образованности, могут быть упакованы в смешанный пакет Graduate_G:

with Degrees; use Degrees; -- экспортирует тип Degree

generic

type Person is tagged private;

package Graduate_G is

-- тип Graduate содержит Degree type Graduate is new Person with private;

procedure Give (G: in out Graduate; D: in Degree); function Degree_of (G: Graduate) return Degree;

private

type Graduate is new Person with

record

Given_Degree: Degree; end record;

end Graduate_G;

При конкретизации этого пакета с формальным параметром настройки тэгового типа Woman, будет создан новый тип, производный от типа указанного при конкретизации.

Этот новый тип будет обладать желаемыми свойствами:

package Graduate_Women is new Graduate_G (Woman);

Anne : Graduate_Women.Graduate; -- тип полученный в результате -- конкретизации Graduate_G D : Degrees.Degree :=...

Christen (Somebody, "Anne"); -- операция типа Woman Give (Somebody, Degree); -- операция типа Graduate

Свойства обоих типов, типа-предка Woman и смешанного типа Graduate, будут доступны для нового типа Graduate_Woman.Graduate.

Тип-предок для смешанного типа (тип формального параметра настройки) может быть ограничен принадлежностью к иерархии наследования какого-либо класса.

Такое ограничение осуществляется для обеспечения гарантии того, что тип-предок обладает требуемым множеством свойств, которые необходимы для реализации смешанного типа, или для гарантирования логичности смешанного типа.

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

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

Следующий пример демонстрирует, что только тип Human и его потомки могут быть использованы для конкретизации смешанного настраиваемого модуля:

with Degrees; use Degrees;

generic

type Person is new Human with private;

package Graduate_G is

type Graduate is new Person with private;

... -- описания Give и Degree_of те же, что и в предыдущем примере

function Title_of (G: Graduate) return String; -- переопределение функции Title_of -- для получения требуемого заголовка

private

... end Graduate_G;

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

Так, например, функция Title_of переопределяется для предоставления более подходящей реализации.


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