Объявление производного типа имеет вид
type <ИмяПроизводногоТипа> is
new <ИмяРодительскогоТипа> [<ОграничениеРодительскогоТипа>];
где ограничение на значения родительского типа могут отсутствовать.
Производный тип наследует у родительского-типа его значения и операции. Набор родительских значений наследуется без права изменения. Наследуемые операции, называемые примитивными операциями, являются подпрограммами, имеющими формальный параметр или результат родительского типа и объявленными в том же пакете, что и родительский тип.
В заголовке каждой из унаследованных операций выполняется автоматическая замена указаний родительского типа на указания производного типа.
Например, пусть сделаны объявления:
type Integer is …; -- определяется реализацией
function "+" (Left. Right: Integer) return Integer;
Тогда любой тип, производный от Integer, вместе с реализацией родительского типа автоматически наследует функцию «+»:
type Length is new Integer;
-- function "+" (Left. Right: Length) return Length;
Здесь символ комментария (--) показывает, что операция «+» наследуется автоматически, то есть от программиста не требуется ее явное объявление. Любая из унаследованных операций может быть переопределена, то есть может быть обеспечена ее новая реализация. О такой операции говорят, что она перекрыта:
|
|
type Угол is new Integer;
function "+" (Left. Right: Угол) return Угол;
В этом примере для функции «+» обеспечена новая реализация (учитывается модульная сущность сложения углов).
По своей сути производный тип — это новый тип данных со своим набором значений и операций, а также со своей содержательной ролью. По значениям, операциям производный тип несовместим ни с родительским типом, ни с любым другим типом, производным от этого же родителя.
По сравнению с родительским типом в производном типе:
q набор значений может быть сужен (за счет ограничений при объявлении);
q набор операций может быть расширен (за счет объявления операций в определяющем для производного типа пакете).
Примеры объявления производных типов:
type Год Is new Integer range 0.. 2099;
type Этаж i s new Integer range 1.. 100;
Если теперь мы введем два объекта:
А: Год;
В: Этаж;
и попытаемся выполнить присваивание
А:= В;
то будет зафиксирована ошибка.