Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прогр.на_ЯВУ_уч.пос.DOC
Скачиваний:
24
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Раннее и позднее связывание

Рассмотрим объектные типы 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.

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

§10.3. Виртуальные методы

Метод становится виртуальным, если после его заголовка стоит служебное слово 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-файлов без исходного кода. Для работы с объектами модулей только необходимо знать содержимое интерфейсной части. Зная его, можно создавать не только компактные описания новых объектов, но и добавлять новые методы к уже существующим. Возможность добавления новых функциональных характеристик в программу без модификации ее исходного текста называется способностью к расширению. С другой стороны, работа с виртуальными методами происходит немного медленнее и требует дополнительных затрат памяти, но это не должно служить препятствием к широкому использованию виртуальных методов.