Технологии разработки программного обеспечения


современный язык программирования, имеющий максимальный


Ada 95 — современный язык программирования, имеющий максимальный набор средств описания данных и действий. Его средства обеспечивают все технологические потребности профессионального.программирования. Конструкции языка поддерживают как традиционный, императивный стиль программирования, так и объектно-ориентированный стиль, позволяют создавать как последовательные, так и параллельные процессы.

 

Типы и объекты данных

Тип данных задает набор возможных значений и набор операций, допустимых над этими значениями. Все типы данных Ada 95 разделяют на две большие группы: элементарные и составные. Данные элементарного типа имеют значения, которые логически неразделимы. Данные составного типа имеют значения, которые составлены из значений компонентов.

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

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

Описание типа приводится в декларативной части программы. Общая форма объявления типа имеет вид

type <ИмяТипа> is <ОпределениеТипа>;

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

Приведем примеры объявления типов:

q       целый знаковый тип

type Temperature is range -70..70:

q       модульный целый тип



type Time_of_Day is mod 86400;

type Day_of_Month is mod 32;

q       вещественный тип с плавающей точкой — задает значения, представляемые восемью десятичными цифрами



type Distance is digits 8;

q       двоичный вещественный тип с фиксированной точкой — задает значения с погрешностью 0,001 в диапазоне от 0.00 до 200.00

type Price is delta 0.001 range 0.00 ..200.00;

q       десятичный вещественный тип с фиксированной точкой — задает значения, представляемые восемью десятичными цифрами с погрешностью 0,1 (то есть значения до 9999999,9)

type Miles is delta 0.1 digits 8;

q       перечисляемый тип

type Day is ( mon. tue. wed, thu. fri. sat. sun );

type Colour is ( red. blue, green, black );

q       тип записи

type Date_Type is

record

Day : Day_Type;

Month : Month_Day;

Year : Year_Type;

end record;

q       тип массива

type Week is array ( 1 .. 7 ) of Day:

Некоторые типы в языке предопределены. Предопределенные типы не нужно объявлять в декларативной части программы. К ним относятся:

q       целый тип Integer с диапазоном значений -32 767...+32 768;

q       вещественный тип с плавающей точкой Float;

q       перечисляемые типы Boolean (логический), Character (символьный);

q       регулярный тип String (задает массивы из элементов символьного типа).

После того как тип объявлен, можно объявлять экземпляры этого типа. Экземпляры типов называются объектами. Объекты содержат значения. Значения объектов-переменных могут изменяться, значения объектов-констант постоянны.

Общая форма объявления объекта имеет вид

<ИмяОбъекта> : [constant] <ИмяТипа> [:=НачальноеЗначение];

где в квадратных скобках указаны необязательные элементы, а НачальноеЗначение — некоторое выражение соответствующего типа.

Примеры объявлений объектов-переменных:

q       символьный объект с начальным значением

Symbol : Character :- 'A';

 

ПРИМЕЧАНИЕ



Значение символьного объекта записывается в апострофах.

q       строковый объект с начальным значением

Name : String ( 1 .. 9 ) := "Aleksandr";

 

ПРИМЕЧАНИЕ

Значение строкового объекта записывается в кавычках.

q       объект перечисляемого типа

Car_Colour : Colour := red;

q       объект модульного типа

Today : Day_of_Month := 31;

 

ПРИМЕЧАНИЕ

Значение этого объекта может изменяться в диапазоне от 0 до 31. К модульному типу применяется модульная арифметика, поэтому после оператора Today := Today + 1 объект Today получит значение 0.

Примеры объявлений объектов-констант:

Time : constant Time_of_Day := 60;

Best_Colour : constant Colour := blue;

Отметим, что если константа является именованным числом (целого и вещественного типа), то имя типа можно не указывать:

Minute : constant := 60;

Hour : constant := 60 * Minute;

 

Текстовый и числовой ввод-вывод

Ada 95 — это язык для разработки программ реального мира, программ, которые могут быть очень большими (включать сотни тысяч операторов). При этом желательно, чтобы отдельный программный файл имел разумно малый размер. Для обеспечения такого ограничения Ada 95 построена на идее библиотек и пакетов. В библиотеку, составленную из пакетов, помещаются программные тексты, предназначенные для многократного использования.

 

Пакеты ввода-вывода

Пакет подключается к программе с помощью указания (спецификатора) контекста, имеющего вид

with <Имя_Пакета>;

Размещение в пакетах процедур ввода-вывода (для величин предопределенных типов) иллюстрирует табл. В.1.

 

Таблица В.1. Основные пакеты ввода-вывода

Имя пакета

Тип вводимых-выводимых величин

Ada.Text_IO

Ada.lnteger_Text_IO

Ada.Float_Text_IO

Character, String

Integer

Float

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


Родовой пакет перед использованием должен быть настроен на конкретный тип.

Как показано в табл. В.2, родовые пакеты ввода-вывода всегда находятся внутри пакета-библиотеки Ada.Text_IO.

 

Таблица В.2. Внутренние пакеты из пакета-библиотеки Ada.Text_IO

Имя родового пакета

Нужна настройка на тип

Integer_IO

Float_IO

Enumeration_IO

Fixed_IO

Decimal_IO

Modular_IO

Любой целый тип со знаком

Любой вещественный тип с плавающей точкой

Любой перечисляемый тип

Любой двоичный вещественный тип с фиксированной точкой

Любой десятичный вещественный тип с фиксированной точкой

Любой целый тип без знака

Для обращения к внутренним родовым пакетам используют составные имена, например Ada.Text_IO.Modular_IO, Ada.Text_IO.Enumeration _IO.

Процесс настройки родового пакета называют конкретизацией. В результате конкретизации образуется экземпляр родового пакета. Экземпляр помещается в библиотеку и может быть подключен к любой программе.

Конкретизация задается предложением следующего формата:

with <Полное имя родового пакета>;

package <Имя пакета-экземпляра> is

new <Имя родового пакета> (<Имя типа настройки>);

Например, введем перечисляемый тип:

Type Summer is ( may. jun, jul. aug );

Создадим экземпляр пакета для ввода-вывода величин этого типа:

with Ada.Text_IO.Enumeration_IO;

package Summer_IO is new Ada.Text_IO.Enumeration_IO (Summer);

Теперь пакет SummerJO может использоваться в любой программе.

 

Процедуры ввода

Формат вызова процедуры:

<ИмяПакета> . Get (<ФактическиеАргументы>);

Например, для ввода величины типа Character записывается оператор вызова

Ada.Text_IO.Get (Var);

В результате переменной Var (типа Character) присваивается значение символа, введенного с клавиатуры. Пробел считается символом, нажатие на клавишу Enter не учитывается.

Еще один пример оператор вызова:

Ada.Integer_Text_IO.Get (Var2);

В этом случае в переменную Var2 типа Integer заносится строка числовых символов.


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

 

Процедуры вывода

В операторе вызова можно указывать не только фактические параметры, но и сопоставления формальных и фактических параметров в виде

Put (<ФактическийПараметр1>,

    <ФормальныйПараметрЗ> => <ФактическийПараметрЗ>, ...);

При такой форме порядок записи параметров безразличен.

Например, по оператору вызова

Ada.Text_IO.Put ( Item => Var3 )

значение переменной Var3 (типа Character) отображается на дисплее, а курсор перемещается в следующую позицию.

По оператору вызова

Ada.Integer_Text_IO.Put ( Var4. Width => 4 )

на экране отображается значение целой переменной Var4, используются текущие Width позиций (в примере — 4). Если значение (включая знак) занимает меньше, чем Width, позиций, ему предшествует соответствующее количество пробелов. Если значение занимает больше, чем Width, позиций, то используется реальное количество позиций. Если параметр Width пропущен, то используется ширина, заданная компилятором по умолчанию.

 

Основные операторы

Оператор присваивания

<ИмяПеременной> := <Выражение>;

предписывает: вычислить значение выражения и присвоить это значение переменной, имя которой указано в левой части.

Условный оператор

if <условие 1> then

<последовательность операторов 1>

elsif <условие 2> then

<последовательность операторов 2>

else

последовательность операторов 3>

end if;

обеспечивает ветвление — выполнение операторов в зависимости от значения условий.

 

ПРИМЕЧАНИЕ

Возможны сокращенные формы оператора (отсутствует ветвь elsif, ветвь else).

Оператор выбора позволяет сделать выбор из произвольного количества вариантов, имеет вид

case < выражение > is

when <список выбора 1> =>

<последовательность операторов 1>





when <список выбора n> =>

<последовательность операторов n>

when others =>

<последовательность операторов n+1>

end case;

Порядок выполнения оператора:

1)      вычисляется значение выражения;

2)      каждый список выбора ( от первого до последнего) проверяется на соответствие значению;

3)      если найдено соответствие, то выполняется соответствующая последовательность операторов, после чего происходит выход из оператора case;

4)      если не найдено соответствие, то выполняются операторы, указанные после условия when others.

Элементы списка выбора отделяются друг от друга вертикальной чертой ('|') и могут иметь следующий вид:

q       <выражение>;

q       <выражение n>..<выражение m>.

Примеры:

case Number is

when 1 | 7 => Put ("Is 1 or 7");

when 5 => Put ("Is 5");

when 25..100 => Put ("Is number between 25 and 100");

when others => Put ("Is unknown number");

end case;

case Answer is

when 'A'..'Z' | 'a'..'z' => Put_Line ("It's a letter!");

when others => Put_Line ("It's not a letter!")

end case;

Оператор блока объединяет последовательность операторов в отдельную структурную единицу, имеет вид

declare

<последовательность объявлений>

begin

<последовательность операторов>

end;

 

ПРИМЕЧАНИЕ

Объявления из раздела declare действуют только внутри раздела операторов блока.

Пример:

declare

Ch : Character;

begin

Ch := 'A';

Put ( Ch );

end;

 

Операторы цикла

Оператор цикла loop

loop

<последовательность операторов 1>

exit when <условие выхода>

<последовательность операторов 2>

end loop;

служит для организации циклов с заранее неизвестным количеством повторений.

Порядок выполнения.

1. Выполняется последовательность операторов 1.



2. Вычисляется значение условия выхода. Если значение равно True, происходит выход из цикла.

3. Выполняется последовательность операторов 2. Осуществляется переход к пункту 1.

 

ПРИМЕЧАНИЕ

Операторы тела повторяются, пока условие равно False. В теле должен быть оператор, влияющий на значение условия, иначе цикл будет выполняться бесконечно. В теле цикла возможно использование безусловного оператора выхода exit или условного оператора выхода exit when <условие>.

Пример:

Count := 1;

loop

Ada.Integer_Text_IO.Put ( Count );

exit when Count = 10;

Count := Count + 1;

end loop:

При выполнении цикла на экран выводится:

12345678910

Аналогичные вычисления можно задать в следующем виде:

Count := 1

loop

Ada.Integer_Text_IO.Put ( Count );

if Count = 10 then

exit;

end if;

Count := Count + 1;

end loop;

Оператор цикла while также позволяет определить цикл с заранее неизвестным количеством повторений, имеет вид

while <условие продолжения> loop

<последовательность операторов>

end loop;

Порядок выполнения.

1. Вычисляется значение условия. Если значение равно True, выполняется переход к пункту 2. В противном случае (при значении False) происходит выход из цикла.

2. Выполняются операторы тела цикла. Осуществляется переход к пункту 1.

Таким образом, это цикл с предусловием.

Перечислим характерные особенности оператора while.

1. Операторы тела могут выполняться нуль и более раз.

2. Операторы тела повторяются, пока условие равно True.

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

Пример:

Count :=1;

loop

while Count <= 10 loop

Put ( Count ):

Count := Count + 1;

end loop;

При выполнении цикла на экран выводится:

12345678910

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

Первая форма оператора for имеет вид:

for <параметр цикла> in <дискретный диапазон> loop

<операторы тела цикла>



end loop;

Параметр цикла — это переменная, которая заранее не описывается (в программе). Данная переменная определена только внутри оператора цикла. Параметру цикла последовательно присваиваются значения из дискретного диапазона. Дискретный диапазон всегда записывается в порядке возрастания в виде

min .. max;

Операторы тела повторяются для каждого значения параметра цикла (от минимального до максимального).

Пример:

for Count in 1 .. 10 loop

Put ( Count );

end loop;

При выполнении цикла на экран выводится:

1 2 3 4 5 б 7 8 9 10

Вторая форма оператора for имеет вид

for <параметр цикла> in reverse <дискретный диапазон> loop

<операторы тела цикла>

end loop;

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

Пример:

for Count in reverse 1 .. 10 loop

Put ( Count );

end loop;

При выполнении цикла на экран выводится:

10987654321

 

ПРИМЕЧАНИЕ

Операторы exit и exit when могут использоваться и в операторах цикла while, for.

 

Основные программные модули

Ada-программа состоит из одного или нескольких программных модулей. Программным модулем Ada 95 является:

q       подпрограмма — определяет действия — подпроцесс (различают две разновидности: процедуру и функцию);

q       пакет — определяет набор логически связанных описаний объектов и действий, предназначенных для совместного использования;

q       задача — определяет параллельный, асинхронный процесс;

q       защищенный модуль — определяет защищенные данные, разделяемые между несколькими задачами;

q       родовой модуль — настраиваемая заготовка пакета или подпрограммы.

Родовой модуль имеет формальные родовые параметры, обеспечивающие его настройку в период компиляции. Родовыми параметрами могут быть не только элементы данных (объекты), но и типы, подпрограммы, пакеты.


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

Как правило, модули можно компилировать отдельно. Обычно в модуле две части:

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

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

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

 

Функции

Функция — разновидность подпрограммы, которая возвращает значение результата.

Спецификация функции имеет вид

function <ИмяФункции> (<СписокФормальныхПараметров>)

return <ТипРезультата>;

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

<ИмяПеременной>:<ТипДанных> := <ЗначениеПоУмолчанию>

Значение по умолчанию может не задаваться.

Пример спецификации:

function Box_Area (Depth : Float; Width : Float) return Float;

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

function <ИмяФункции> (<СписокФормальныхПараметров>)

return <ТипРезультата> is

<объявления локальных переменных и констант>

begin

<операторы>

return <результат>; -- оператор возврата результата

end <ИмяФункции>;

Пример тела функции:

function Box_Area (Depth : Float; Width ; Float) return Float is

Result : Float;

begin

Result := Depth * Width;

return Result: -- возврат вычисленного значения

end Box_Area;

Описание тела функции само по себе действий не производит. Для выполнения функции необходимо ее вызвать. Чтобы вызвать функцию, записывают ее имя и список фактических параметров, запись помещается в правую часть оператора присваивания:



<ИмяПеременной> := <ИмяФункции> (<СписокФактическихПараметров>);

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

Пример вызова:

Му_Вох := Вох_Агеа ( 2.0. 4.15 );

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

 

Процедуры

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

procedure <ИмяПроцедуры> (<СписокФормальныхПараметров>);

Для записи каждого формального параметра принят следующий формат:

<Имя> : <Вид> <Тип данных>;

где <Вид> указывает направление передачи информации между формальным и фактическим параметрами (in — передача из фактического в формальный параметр, out — из формального в фактический параметр, in out — двунаправленная передача).

 

ПРИМЕЧАНИЕ

Пометку in разрешается не указывать (она подразумевается по умолчанию), поэтому в спецификации функции вид параметра отсутствует. Для формального параметра вида in разрешается задавать начальное значение, присваиваемое по умолчанию.

Пример спецификации:

procedure Sum ( Opl : in Integer := 0; Op2 : in Integer := 0;

Op3 : in Integer := 0: Res : out Integer );

Тело процедуры в общем случае имеет вид

procedure <ИмяПроцедуры>

(<СписокФормальныхПараметров>) is

<объявления локальных переменных и констант>

begin

<операторы>

end <ИмяПроцедуры>;

Пример тела:

procedure Sum ( Opl : in Integer := 0; Op2 : in Integer := 0;

Op3 : in Integer := 0: Res : out Integer ) is

begin

Res := Opl + Op2;

Res := Res + Op3;

 end Sum;

В данной процедуре три формальных параметра имеют значения по умолчанию. Это дает интересные возможности.

Обращаются к процедуре с помощью оператора вызова, он имеет вид

<ИмяПроцедуры> (<СписокФактическихПараметров>);



Примеры операторов вызова:

Sum (4. 8, 12. d); -- переменная d получит значение 24

Sum (4. 8. Res => d); -- переменная d получит значение 12

 

ПРИМЕЧАНИЕ

В первом операторе вызова задано 4 фактических параметра, во втором операторе — 3 фактических параметра. Во втором операторе использованы как традиционная (позиционная) схема, так и именная схема сопоставления формального и фактического параметров.

 

Пакеты

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

Спецификация пакета объявляет предлагаемые услуги, а тело содержит реализацию этих услуг.

Спецификация пакета записывается в виде

package <ИмяПакета> is

<объявления типов, переменных, констант>

<спецификации процедур и функций>

          end <ИмяПакета>;

Пример спецификации:

package Рисование is

type Точка is array ( 1 .. 2 ) of Integer;

-- описание точки в прямоугольной системе координат

procedure Переход ( из : in Точка; в : in Точка );

-- переход из одной точки в другую точку

procedure Рисовать_Линию (от : in Точка; до : in Точка );

-- рисуется сплошная линия между заданными точками

procedure Рисовать_Пунктирную_Линию (от : in Точка: до ; in Точка );

-- рисуется пунктирная линия

end Рисование;

Данная спецификация предлагает клиентам один тип данных и три процедуры.

Тело пакета представляется в виде

package body <ИмяПакета> is

<объявления локальных переменных, констант. типов>

<тела процедур и функций>

          end <ИмяПакета>;

Еще раз отметим, что содержание тела пакета клиентам недоступно.

Пример тела:

package body Рисование is

-- локальные объявления

procedure Переход ( из : in Точка: в : in Точка ) is

-- локальные объявления

begin

-- операторы

end Переход;

procedure Рисовать_Линию(от : in Точка: до ; in Точка) is



-- локальные объявления

begin

-- операторы

end Рисовать_Линию;

procedure Рисовать_Пунктирную_Линию ( от : in Точка;

до : in Точка ) is

-- локальные объявления

begin

-- операторы

end Рисовать_Пунктирную_Линию;

end Рисование:

В спецификации пакета может быть полузакрытая (приватная) часть. Эта часть отделяется от обычной (открытой) части служебным словом private. Содержимое приватной части пользователю (клиенту) недоступно. В эту часть помещают скрываемые от пользователя операции и детали описания типов данных. Заметим, что из тела пакета доступно содержание как открытой, так и приватной части спецификации.

 

Производные типы

Объявление производного типа имеет вид

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;

Если теперь мы введем два объекта:

А : Год;

В : Этаж;

и попытаемся выполнить присваивание

А := В;

то будет зафиксирована ошибка.

 

Подтипы

Очень часто для повышения надежности программы приходится ограничивать область значений типов и объектов, не затрагивая при этом допустимые операции. Для такого ограничения удобно использовать понятие подтипа.

Подтип — это сочетание типа и ограничения на допустимые значения этого типа. Объявление подтипа имеет вид

subtype <ИмяПодтипа> is <ИмяТипа> range <Ограничение>;

Характерные особенности подтипов:

q       подтип наследует все операции, которые определены для его типа;

q       объект подтипа совместим с любым объектом его типа, удовлетворяющим указанному ограничению;

q       содержательные роли объектов различных подтипов для одного типа аналогичны.

Таким образом, объекты типа и его подтипов могут свободно смешиваться в арифметических операциях, операциях сравнения и присваивания.

Например, если в программе объявлен перечисляемый тип День_Недели, то можно объявить подтип



subtype Рабочий_День is День_Недели range ПОНЕДЕЛЬНИК..ПЯТНИЦА;

При этом гарантируется, что объекты подтипа Рабочий_День будут совместимы с объектами типа День_Недели.

 

Расширяемые типы

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

Рассмотрим построение иерархии геометрических объектов. На вершине иерархии точка, имеющая два свойства (координаты X и Y):

type Точка Is tagged

record

Х_КоорД : Float;

Y_Koopfl : Float;

end record;

Другие типы объектов можно произвести (прямо или косвенно) от этого типа.

Например, можно ввести новый тип, наследник точки:

type Окружность is new Точка with -- новый теговый тип;

record

Радиус : Float;

end record;

Данный тип имеет три свойства: два свойства (координаты X и Y) унаследованы от типа Точка, а третье свойство (Радиус) нами добавлено. Дочерний тип Окружность наследует все операции родительского типа Точка, причем некоторые операции могут быть переопределены. Кроме того, для дочернего типа могут быть введены новые операции.

 


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