Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочник Pascal ABC.doc
Скачиваний:
67
Добавлен:
07.11.2018
Размер:
985.6 Кб
Скачать

Виртуальные методы и полиморфизм

Пусть переопределенный в подклассе метод базового класса имеет тот же список формальных параметров (а для функций - и тип возвращаемого значения). Например:

type   Base=class     procedure Print;     begin       writeln('Base');     end;   end;   Derived=class(Base)     procedure Print;     begin       writeln('Derived');     end;   end;

Рассмотрим различные способы вызова метода Print:

var   b,b1: Base;   d: Student;   ...   b:=Base.Create;   d:=Derived.Create;   b1:=d;   b.Print; // вызывается Base.Print   d.Print; // вызывается Derived.Print   b1.Print;

Какая версия метода Print вызывается в последнем случае - класса Base или класса Derived? В объектно-ориентированных языках программирования возможны две ситуации. Если решение о том, какой метод вызывать, принимается на этапе компиляции на основании типа, заявленного при описании b1, то вызывается метод Base.Print (говорят также, что имеет место раннее связывание имени метода с его телом). Если же решение о том, какой метод вызывать, принимается на этапе выполнения программы в зависимости от реального типа объекта, на который ссылается переменная b1, то вызывается метод Derived.Print (говорят также, что имеет место позднее связывание). Методы, для которых реализуется позднее связывание, называются виртуальными, а способность объекта вызывать через переменную базового класса метод производного класса на основании информации во время выполнения программы называется полиморфизмом.

В языке Pascal ABC все методы (за исключением конструкторов) являются виртуальными, т.е. в последнем случае вызовется функция Derived.Print.

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

type   Shape=class     procedure Draw; begin end;   end;   Point=class     procedure Draw; begin ... end;   end;   Rectangle=class     procedure Draw; begin ... end;   end;   Circle=class     procedure Draw; begin ... end;   end; var a: array[1..4] of Shape; ...   a[1]:=Point.Create;   a[2]:=Rectangle.Create;   a[3]:=Point.Create;   a[4]:=Circle.Create;   for i:=1 to 4 do     a[i].Draw;

В данном случае в качестве единого действия выступает метод Draw, но каждый объект выполняет его по-своему, обеспечивая полиморфное поведение. Говорят, что методы Draw в базовом классе Shape и его потомках образуют цепочку виртуальности.

Внимание! Если переопределяется private-метод, то цепочка виртуальности ломается, т.е. метод рассматривается как первый с этим именем в новой цепочке виртуальности.

Модули

Модули предназначены для разбиения текста программы на несколько файлов. В модулях описываются переменные, константы, типы, классы, процедуры и функции. Для того чтобы эти объекты можно было использовать в вызывающем модуле (которым может быть и основная программа), следует указать имя файла модуля (без расширения .pas) в разделе uses вызывающего модуля. Файл модуля должен находиться либо в том же каталоге, что и основная программа, либо в подкаталоге Units системного каталога программы Pascal ABC.

Модуль в Pascal ABC представляет собой файл со следующим содержанием:

unit имя модуля; раздел подключения модулей раздел описаний раздел инициализации раздел финализации end.

Первая строка обязательна и называется заголовком модуля.

Раздел подключения модулей начинается со служебного слова uses, за которым следует список имен модулей, перечисляемых через запятую.

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

Раздел инициализации состоит из служебного слова initialization, после которого следуют операторы, разделяемые символом "точка с запятой". Операторы из раздела инициализации модуля выполняются до начала основной программы.

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

Раздел финализации может отсутствовать, либо оба раздела инициализации и финализации могут отсутствовать. Раздел инициализации может также начинаться со служебного слова begin, в этом случае раздел финализации отсутствует.

Например:

unit Lib; uses GraphABC; const Dim=5; var Colors: array [1..Dim] of integer; function RandomColor: integer; begin   Result:=RGB(Random(255),Random(255),Random(255)); end; procedure FillByRandomColor; var i: integer; begin   for i:=1 to Dim do     Colors[i]:=RandomColor; end; initialization   FillByRandomColor; end.

Поскольку система Pascal ABC не создает кода на диске, модули являются по-существу аналогом включаемых файлов. В частности, они компилируются всякий раз при компиляции основной программы. Однако, если при компиляции программы один и тот же модуль подключается в нескольких модулях, то этот модуль компилируется лишь раз.

Циклические ссылки в модулях запрещены. Например, ситуация, когда в в модуле a.pas присутствует строка uses b, а в модуле b.pas - строка uses a, считается ошибочной.