ООП на языке Ада
Основная цель расширяемых типов — обеспечить повторное использование существующих программных элементов (без необходимости перекомпиляции и перепроверки). Они позволяют объявить новый тип, который уточняет существующий родительский тип наследованием, изменением или добавлением как существующих компонентов, так и операций родительского типа.
В качестве расширяемых типов используются теговые типы (разновидность комбинированного типа).Рассмотрим построение иерархии геометрических объектов. На вершине иерархии находится точка, имеющая два атрибута (координаты X и Y): type Точка is tagged record
x_Коорд : Float;
У_Коорд : Float; end record;
Другие типы объектов можно произвести (прямо или косвенно) от этого типа.
Например, можно ввести новый тип, наследник точки: type Окружность is new Точка with -- новый теговый тип; record
радиус : Float; end record;
Данный тип имеет три атрибута: два атрибута (координаты x и у) унаследованы от типа Точка, а третий атрибут (радиус) нами добавлен.
Дочерний тип Окружность наследует все операции родительского типа Точка, причем некоторые операции могут быть переопределены. Кроме того, для дочернего типа могут быть введены новые операции.
Классы В языке Ада нет синтаксической конструкции «класс». Для моделирования конструкции «класс» здесь применяют конструкцию «пакет». Пакет — это элегантный способ инкапсуляции программного кода и данных, взаимодействующих друг с другом, в единый модуль. Пакет может экспортировать один или несколько пользовательских типов вместе с их примитивными операциями. Примитивная операция определяется для типа (в части аргументов и результата) и объявляется вместе с типом в одной спецификации пакета. Правила моделирования класса 1. Имени класса придается префикс Класс_.2. Пакет имеет единственный теговый приватный тип, который получает имя класса и используется для объявления экземпляров класса. Вследствие этого все экземпляры класса будут разделять одинаковую структуру и поведение. 3. Процедуры и функции используются для определения поведения класса. Первым параметром для процедуры или функции является экземпляр класса. |
ООП на языке Ада |
485 |
4. Реализация приватного типа определяется как комбинированный расширяемый тип. (Это дает возможность расширять количество полей данных в классах-наследниках, а также количество операций.) Компоненты комбинированного типа определяют структуру данных класса. Например, класс Счет задается в виде следующего пакета: package Класс_Счет is type Счет is tagged private; -- осн. тип класса -- используется для объявления экземпляров subtype Деньги is Float; -- вспомог. типы subtype РДеньги is Float range 0.0.. Float'LAST; -- используются в сообщениях, посылаемых в экз. -- объявления методов класса: procedure заявить ( the : in Счет ); procedure положить ( the : in out Счет; Сумма : in РДеньги ); procedure снять ( the : in out Счет; сумма : in РДеньги; принимать : out РДеньги ); function баланс ( the : Счет ) return Деньги; private -- скрытое представление класса type Счет is tagged record остаток : Деньги := 0.00; -- сумма на счету end record; end Класс_Счет; -- Тело пакета-класса включает реализацию его методов: with Ada.Text_IO, Ada.Float_Text_IO; use Ada.Text_IO, Ada.Float_Text_IO; package body Класс_Счет is procedure заявить ( the : in Счет ) is begin Put ("Тек. состояние : Сумма на вкладе $"); Put ( the.остаток, Aft => 2, Exp => 0); New_Line ( 2 ); end заявить; procedure положить ( the : in out Счет; сумма : in РДеньги ) is begin the.остаток := the.остаток + сумма; end положить; procedure снять ( the : in out Счет; сумма : in РДеньги; принимать : out РДеньги ) is begin if the.остаток >= сумма then the.остаток := the.остаток - сумма; принимать := сумма; else принимать := 0.00; end if; end снять; function баланс ( the : Счет ) return Деньги is begin return the.остаток; end баланс; end Класс_Счет; Видим, что для доступа к полю данных остаток, содержащемуся в экземпляре Счета, используется составное имя ^в.остаток. Например, в функции баланс результат возвращается с помощью оператора return the.остаток; |
486 Глава 16. Объектно-ориентированное и аспектно-ориентированное программирование |
Составное имя используется для доступа к атрибуту экземпляра комбинированного типа. В этом случае экземпляром типа запись является объект the, а атрибутом объекта — поле остаток. К объектам класса (типа) Счет применимы следующие операции: ? обработка (предвыполнение) при создании объекта; ? присвоение значения экземпляра другому экземпляру такого же типа; ? сравнение экземпляров класса на эквивалентность и неэквивалентность; ? заданные методы (чтение и изменение внутреннего состояния возможно только в результате действия методов класса). Если мы объявили объект класса Счет мой_Счет: Класс_Счет.Счет; то можно использовать две формы обращения к его операциям: 1. положить (мой_Счет, деньги); 2. мой_Счет.положить (деньги); В первой форме в качестве первого аргумента вызываемой операции указывается имя объекта (которому принадлежит эта операция). Во второй форме сообщение начинается с указания имени адресуемого объекта, поэтому из списка аргументов операции имя объекта изымается. Вторая форма соответствует традиционному стилю записи сообщений, принятому в объектно-ориентированном программировании. |