PASCAL ABC
Виртуальные методы и полиморфизм
Пусть переопределенный в подклассе метод базового класса имеет тот же список формальных параметров (а для функций - и тип возвращаемого значения). Например:
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-метод, то цепочка виртуальности ломается, т.е. метод рассматривается как первый с этим именем в новой цепочке виртуальности.
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.