виртуальная функция самого младшего класса,
end;
{ виртуальная функция самого младшего класса, вызывает
напрямую метод “дедушки”, минуя “отца”}
function TLevel3.VirtualFunction: string;
var
ClassOld: TClass;
begin
ClassOld := PClass(Self)^;
PClass(Self)^ := Self.ClassParent.ClassParent;
Result := VirtualFunction + ' Level3';
PClass(Self)^ := ClassOld;
end;
function Level1Always(MyObject: TObject): string;
var
ClassOld: TClass;
begin
ClassOld := PClass(MyObject)^;
PClass(MyObject)^ := TLevel1;
Result := (MyObject as TLevel1).VirtualFunction;
PClass(MyObject)^ := ClassOld;
end;
Как же это работает? Стандартные, так называемые объектные типы (object types - class of ...), на самом деле представляют из себя указатель на VMT (Virtual Method Table) - таблицу виртуальных методов, который (указатель) лежит по смещению 0 в экземпляре класса. Воспользовавшись этим, мы сначала сохраняем 'старый тип класса' - указатель на VMT, присваиваем ему указатель на VMT нужного класса, делаем вызов и восстанавливаем все как было. Причем нигде не требуется, чтобы один из этих классов был бы порожден от другого, т.е. функция Level1Always
вызовет требуемый метод для любого экземпляра любого класса.
Если в функции Level1Always
попробовать сделать вызов
Result := MyObject.VirtualFunction;
то будет ошибка на стадии компиляции, так как у класса TObject
нет метода VirtualFunction.
Другой вызов
Result := (MyObject as TLevel3).VirtualFunction;
будет пропущен компилятором, но вызовет Run-time ошибку, даже если передается экземпляр класса TLevel3 или один из его потомков, так как информация о типе объекта была изменена.
Динамически распределяемые (dynamic) методы можно вызывать точно таким же образом, т.к. информация о них тоже хранится в VMT.
Статические методы объектов вызываются гораздо более простым способом, например
var
MyLevel3: TLevel3;
...
(MyLevel3 as TLevel1).SomeMethode;
вызовет метод класса TLevel1
даже если у MyLevel3
есть свой такой же метод.
Содержание Назад
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий