Студопедия
rus | ua | other

Home Random lecture






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


Date: 2015-10-07; view: 404.


 

Имеем описания двух объектовых типов:

Type Point =Object

x, y: integer;

v: boolean;

Procedure Init (a, b: integer);

Procedure SwitchOn;

Procedure SwitchOff;

Procedure Move (dx, dy: integer);

Function GetX: integer;

Function GetY: integer;

End;

Type Circle =Object (Point)

Radius: integer;

Procedure Init (a, b, R: integer);

Procedure SwitchOn;

Procedure SwitchOff;

Procedure Move (dx, dy: integer);

Function GetR: integer;

End;

Алгоритм метода Move похож для обоих типов, поэтому определим его для объектового типа Point, а тип-потомок Circle унаследует его без переопределения:

Procedure Move (dx, dy: integer);

begin

SwitchOff;

x:=x+dx; y:=y+dy;

SwitchOn;

end;

Имеем экземпляры двух объектов рассматриваемых типов:

Var ObPoint: Point;

ObCircle: Circle;

В случае такого описания объектовых типов при выполнении следующих двух сообщений: ObPoint.Move (20, 30); ObCircle.Move (10, 15); возникает коллизия. Причиной ее является то, что унаследованный метод Move жестко связан с методом Point, поэтому метод Move всегда будет вызывать метод Point.SwitchOff. Связь этих методов является статической, т.к. она была определена при компиляции. Таким образом, при выполнении сообщения ObCircle.Move (10, 15); на экране также будет перемещаться точка, а не круг.

 
 

 


Таким образом, если мы имеем один метод для различных объектов, то необходимо разорвать статическую связь, а также обеспечить возможность для Move подключать либо метод Point.SwitchOff, либо метод Circle.SwitchOff в зависимости от того, какой объект вызывает Move. Такой механизм называется динамическим или поздним связыванием и достигается с помощью применения виртуальныхметодов.

Для того, чтобы определить виртуальный метод, необходимо указать после его заголовка в объектовом типе служебное слово virtual. При этом во всех потомках объектового типа переопределяющие методы должны также специфицироваться как виртуальные; кроме того, они должны иметь такой же набор формальных параметров, что и самый первый виртуальный метод. Таким образом, для правильного выполнения нашего примера, вышеуказанные объекты должны быть описаны следующим образом:

Type Point =Object

…………………….

Constructor Init (a, b: integer);

Procedure SwitchOn; virtual;

Procedure SwitchOff; virtual;

Procedure Move (dx, dy: integer);

…………………….

End;

Type Circle =Object (Point)

…………………….

Constructor Init (a, b, R: integer);

Procedure SwitchOn; virtual;

Procedure SwitchOff; virtual;

…………………….

End;

В этом случае, при выполнении цепочки вызовов ObPoint.Move (20, 30); ObCircle.Move (10, 15); один и тот же метод Move будет работать по-разному в зависимости от того, какой объект этот метод вызывает. Такое свойство называется полиморфизмом.

При виртуализации методов должны выполняться следующие условия:

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

2. Если переопределяется реализация виртуального метода, то заголовок заново определяемого виртуального метода в производном типе или объекте не может быть изменен.

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

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

 


<== previous lecture | next lecture ==>
Наследование и переопределение. | Динамические объекты. Деструкторы.
lektsiopedia.org - 2013 год. | Page generation: 3.087 s.