Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Delphi_2.doc
Скачиваний:
31
Добавлен:
28.03.2015
Размер:
494.59 Кб
Скачать

3.7. Статические методы

3.7.1. Понятие статического метода

По умолчанию, методы являются статическими. Пример описания:

Type

TFigure = class

procedure Draw;

end;

TRectangle = class(TFigure)

procedure Draw;

end;

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

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

3.8.1. Понятие виртуального метода

Виртуальные методы, в отличие от статических могут быть перекрыты в классах-потомках.

1. Объявление виртуального метода в базовом классе выполняется с помощью ключевого слова virtual, а его перекрытие в производных классах — с помощью ключевого слова override.

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

Type

TFigure = class

procedure Draw; virtual;

end;

TRectangle = class(TFigure)

procedure Draw; override;

end;

TEllipse = class(TFigure)

procedure Draw; override;

end;

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

var

Figure: TFigure;

rectangle: Trectangle;

Ellipse: Tellipse;

begin

Ellipse.visible:=true; //Draw, Hide от TEllipse

Rectangle.visible:=false; //Draw, Hide от TRectangle

end;

Работа виртуальных методов основана на механизме позднего связывания (late binding). В отличие от раннего связывания (early binding), характерного для статических методов, позднее связывание основано на вычислении адреса вызываемого метода при выполнении программы. Адрес метода вычисляется по хранящемуся в каждом объекте описателю класса.

3.8.2. Механизм вызова виртуальных методов

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

Все процедурные переменные с адресами виртуальных методов пронумерованы и хранятся в таблице, называемой таблицей виртуальных методов (VMT — от англ. Virtual Method Table). Такая таблица создается одна для каждого класса объектов, и все объекты этого класса хранят на нее ссылку.

Структуру объекта в оперативной памяти поясняет рисунок 3.3:

Рисунок 3.3. Структура объекта TTextReader в оперативной памяти

Вызов виртуального метода осуществляется следующим образом:

  1. Через объектную переменную выполняется обращение к занятому объектом блоку памяти;

  2. Далее из этого блока извлекается адрес таблицы виртуальных методов (он записан в четырех первых байтах);

  3. На основании порядкового номера виртуального метода извлекается адрес соответствующей подпрограммы;

  4. Вызывается код, находящийся по этому адресу.