Раздел 7.3 - Динамическая диспетчеризация (полиморфизм) в Ada

В Ada 95 также существует концепция класса. Для любого тегового типа T существует связанный с ним тип T'Class; этот тип является объединением всех типов в дереве наследуемых типов, в основании которого находится тип T. Например, в предыдущем примере Rectangle'Class является классом, который включает типы Rectangle и Square; Figure'Class является классом, включающим типы Circle, Rectangle и Square.

Заметим, что в Ada 95 термин ``класс'' имеет более узкое значение, нежели в некоторых других языках объектно-ориентированного программирования (таких как C++). В C++ этот термин может означать либо "специфический тип" либо "набор специфических типов, которые от него прямо или косвенно наследуются". В Ada 95 для обозначения этих концепций используются различные термины.

В подпрограмме могут быть определены один или более параметров типа T'Class. Любой тип T и каждый из его наследников допустимы в качестве параметра типа T'Class такой подпрограммы. Этот параметр можно без проблем передать любой другой подпрограмме, которая принимает параметр того же типа T'Class. Что же произойдет, если подпрограмма, принимающая некий параметр типа T'Class затем пытается вызвать какую-то другую подпрограмму, требующую конкретизации типа параметра? Ответ - динамическая диспетчеризация.

Динамическая диспетчеризация - это всего лишь определение того, какую именно подпрограмму вызывать и ее вызов во время исполнения программы. Как это делает Ada? Каждая величина, имеющая тэговый тип, содержит невидимый "тэг", который сообщает Ada действительный тип данной величины. Тэг и используется для определения того, какую подпрограмму вызывать. Правила компиляции, имеющиеся в Ada, гарантируют, что в результате динамической диспетчеризации необходимая подпрограмма всегда будет найдена.

На самом деле, это проще показать, чем объяснить. Допустим, необходимо создать подпрограмму, принимающую в качестве параметра произвольную фигуру (Figure). Она должна выводить на экран фразу "Площадь =" и затем вызывать соответствующую данному типу фигуры подпрограмму Area. Ниже приведен пример того, как это можно сделать:

 procedure Print_Area(F : in Figure'Class) is
 begin
   Put("Площадь = ");
   Put( Area(F) );  -- Вызов необходимой подпрограммы вычисления площади для фигуры F
                    -- и вывод результата.
   New_Line;
 end Print_Area;

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

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


Упражнение:

Имеется следующий пакет:


Verbose Configure

Определите количество различных типов, котрый включает Monster'Class в пакете Critters:

  1. 1
  2. 2
  3. 3
  4. 4

Вы можете также:

PREVIOUS Перейти к предыдущему разделу

NEXT     Перейти к следующему разделу

OUTLINE  Вернуться к содержанию Урока 7

David A. Wheeler (dwheeler@ida.org)

Перевод: Юрий Королев   Общая редакция перевода: Г.Ю. Сисюк

Исходная копия этого документа находится по адресу "http://www.adahome.com/Tutorials/Lovelace/s7s3.htm".

Исходная копия перевода размещена на сайте http://www.ada-ru.org