Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_KAZYMYR.doc
Скачиваний:
14
Добавлен:
09.11.2019
Размер:
3.71 Mб
Скачать

4.3.Поліморфізм в Delphi

В Delphi полиморфічними властивостями володіють методи, позначені як virtual або dynamic.

procedure MyProc1; virtual;

procedure MyProc2; dynamic;

Загальне для них полягає в тому, що при їхньому виклику здійснюється пізнє зв'язування, а різниця – у використовуваних таблицях: для virtual – це VMT, а для dynamicDMT (Dynamic Method Table) таблиці. Різниця цих таблиць складається в наступному. В VMT зберігаються адреси всіх віртуальних методів класу, включаючи й методи суперкласу. А в DMT зберігаються адреси тільки тих динамічних методів, які описані в даному класі. Таким чином, virtual методи вимагають більше пам'яті, але швидше викликаються, dynamic методи вимагає менше пам'яті, але їхній пошук ускладнюється.

О днак ефективність по пам'яті в Delphi менш критична в порівнянні з C++, тому що VMT і DMT зберігаються в сегменті коду, у той час, як VMT в C++ зберігаються в сегменті даних.

Структура об'єктів в Delphi з обліком VMT і DMT наведена на рис. 4.5.

Рис. 4.5. Структура об'єктів в Delphi з VMT і DMT

Поле RTTI (RunTimeType Information – інформація часу виконання) має приблизно наступний формат (формат RTTI не документується):

RTTI = record

vtDynamicTable : word; {покажчик на VMT}

vtClassName: word; {пок. на метод, що повертає ім'я класу}

vtInstSize : word; {пок. на метод, що повертає розмір екземпляра}

vtParent : word; {пок. на метод, що повертає предка}

vtNewInst : word; {конструктор}

vtFreeInst : word; {деструктор}

Оскільки RTTI властива класу, то вона може використовуватися для створення його екземпляра. Доступ до RTTI поза методами класу можна одержати, описавши покажчик на клас, тобто на RTTI:

type

TNewClass = class;

TClass = class of TNewClass;

Для основних класів ієрархії Delphi покажчики на них вже визначені за замовчуванням і мають вигляд:

TContlorClass

TComponentClass

Покажчики на клас підкоряються правилу приведення об'єктних типів: покажчик на клас-предок може посилатися на будь-який клас нащадок, але не навпаки.

Найважливіші методи класу визначені в TObject. Вони дозволяють витягти всю необхідну інформацію про клас:

сlass function ClassName: string; {ім'я класу}

сlass function ClassParent: TClass; {клас-предок}

сlass function InstanceSize: word; {розмір екземпляра}

Наприклад, якщо потрібно витягти ім'я класу, варто скористатися наступним кодом:

type

TMyClass = class;

TRefClass = class of TObject;

var

MyRef : TRefClass;

s: string;

begin

MyRef := TObject;

s := MyRef.ClassName; {s одержить значениеTObject}

MyRef := TMyRef;

s := MyRef.ClassName; {s одержить значення TMyRef}

end.

4.3.1.Заміщення віртуальних і динамічних методів

В Delphi метод предка заміщається в тому випадку, якщо для нього зазначена директива override. Якщо її не вказати, то метод не заміщається, тобто ланцюжок поліморфізму розривається:

Приклад 4.1:

type TFirst = class

procedure StatMethod;

procedure VirtProc1; virtual;

procedure VirtProc2; virtual;

procedure DynaProc1; dynamic;

procedure DynaProc2; dynamic;

procedure Broken; virtual;

end;

TSecond = class (TFirst)

procedure StatMethod; override; // помилка

procedure VirtProc1; virtual; // заміщення

procedure DynaProc1; dynamic; // заміщення

procedure Broken; virtual; // заміщення немає

end;

var

theObj1: TFirst;

theObj2: TSecond;

begin

theObj1:= TFirst.Create;

theObj2:= TSecond.Create;

……………………………

end......

Застосування override до статичного методу викликає помилку компіляції, а до віртуального й динамічного методу приводить до його заміщення. Якщо метод у класі-нащадку оголошується як віртуальний, то заміщення не відбувається, а створюється новий віртуальний метод і ланцюжок поліморфізму обривається.

Структура об'єктів для даного приклада наведена на рис 4.6:

Рис. 4.6. Структура об'єктів для приклада 4.1

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]