Раннее и позднее связывание
Рассмотрим объектные типы Point и Circle. Они связаны отношением наследования и содержат, наряду с другими, методы SwitchOn, SwithOff и Move. Первые два из них реализуют алгоритмы рисования и удаления фигуры с экрана, они существенно различны для разных типов. Алгоритм же метода Move практически одинаков для обоих типов: удаление фигуры со старого места, изменение ее координат и рисование на новом месте. Например:
Procedure Move (dx, dy: integer);
Begin
SwitchOff;
X:=X+dx;
Y:=Y+dy;
SwitchOn;
end;
Рассмотрим вариант унаследования этого метода без переопределения. Пусть имеются экземпляры двух разных объектов:
Var
OnePoint: Point;
OneCircle: Circle;
то вызовы методов
OnePoint.Move (10, -20);
OneCircle.Move (10, -20);
приведут к одному и тому же действию: перемещению точки. Это связано с тем, что экземпляр типа-потомка вызывает унаследованный метод Move, который жестко связан с методами Point.SwitchOn и Point.SwitchOff на ранней стадии, то есть еще во время компиляции программы. В данном случае связь методов является статической.
Для того, чтобы в полной мере использовать свойство полиморфизма и использовать одни и те же унаследованные методы, по-разному применяемые к разным объектам, необходимо, во-первых, разорвать связь метода Move с методами предка Point, во-вторых, обеспечить возможность вызывать разные методы SwitchOn и SwitchOff в зависимости от того, какой объект вызывает Move.
Это можно реализовать только во время вызова метода, то есть в процессе выполнения программы, поэтому такой механизм называется динамическим илипоздним связываниеми достигается введением виртуальных методов.
Виртуальные методы
Метод становится виртуальным, если после его заголовка стоит служебное слово Virtual. Необходимо помнить, что если метод в родительском типе объявлен как виртуальный, то все одноименные методы у потомков так же должны быть виртуальными. Кроме того, они все должны иметь одинаковый набор формальных параметров, что и самый первый виртуальный метод.
Если объекты являются динамическими, то, по аналогии с динамическими переменными они должны создаваться и уничтожаться. Для этого введены понятия «Конструктор» и «Деструктор», которые обсуждаются далее. Так, типы Point и Circle можно определить следующим образом:
Type
Point = object
…
Constructor Create (a, b: integer);
Destructor Done; VIRTUAL;
Procedure SwitchOn; VIRTUAL;
Procedure SwitchOff; VIRTUAL;
Procedure Move (dx, dy: integer);
end;
Circle = object (Point)
…
Constructor Create (a, b, R: integer);
Procedure SwitchOn; VIRTUAL;
Procedure SwitchOff; VIRTUAL;
end;
Полные описания методов остаются такими же, как и раньше. Теперь обращения к методам
OnePoint.Move (10, -20);
OneCircle.Move (10, -20);
дадут разный результат, то есть определение виртуального метода можно представить как шаблон для всех родственных ему методов.
Свойство полиморфизма предоставляет очень широкие возможности при разработке программ. Типы объектов и методы, определенные в различных модулях, могут поставляться пользователям в виде TPU-файлов без исходного кода. Для работы с объектами модулей только необходимо знать содержимое интерфейсной части. Зная его, можно создавать не только компактные описания новых объектов, но и добавлять новые методы к уже существующим. Возможность добавления новых функциональных характеристик в программу без модификации ее исходного текста называется способностью к расширению. С другой стороны, работа с виртуальными методами происходит немного медленнее и требует дополнительных затрат памяти, но это не должно служить препятствием к широкому использованию виртуальных методов.
Дата добавления: 2016-06-29; просмотров: 1528;