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

Virtual; Abstract;

Procedure <имя метода>[(<параметры>)]; Dynamic; Abstract;

Function <имя метода>[(<параметры>)]: <тип результата>;

Dynamic; Abstract;

В VMT (DMT) для абстрактного метода резервируется строка, в которую вместо адреса вызова метода заносится Nil.

В общем контексте под виртуальными методами понимают как собст­венно виртуальные методы, так и динамические методы или Override-методы (замещаемые).

Таким образом, у каждого классового типа имеется своя уникальная VMT. Блок данных экземпляра класса, в свою очередь, содержит скрытый указатель на VMT своего классового типа. Когда транслятору необходимо сгенерировать код для вызова виртуального метода, он сначала генерирует код для получения указателя на VMT из данных экземпляра класса (первого поля), затем получает адрес кода нужного метода из соответствующего поля VMT, после чего выполняет вызов по полученному адресу. Реально на все это требуется две машинные инструкции.

Примечание:

Объявления методов, как и полей можно переносить из одного разде­ла в другой. Невозможно только переносить объявления из раздела Private в раздел с большей видимостью.

е) Повторное объявление методов (перегрузка методов).

Повторное объявление обычных процедур и функций, а также методов позволяет создавать подпрограммы с одинаковыми именами, но с несколько различными возможностями. Исторически перегрузка впервые была введена в C++ для того, чтобы позволить использование нескольких конструкторов с одинаковым именем (именем класса). В ОР эта возможность не считалась не­обходимой просто потому, что здесь можно объявлять конструкторы с раз­ными именами. Однако из-за интеграции Delphi и C++ Builder фирма Borland пошла на введение этой особенности в ОР.

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

Для указания компилятору о tqm, что подпрограммы, включая конструк­торы и статические методы, имеют одинаковые имена, используется слово-директива Overload у каждой из них, при объявлении в одном классе или у предка и потомка. Подпрограммы, объявленные с директивой Overload, должны различаться или числом или типом параметров (тип результата функции не является различием). Оба перегружаемых метода доступны, даже если второй определен в классе-наследнике, поскольку компилятор опреде­лит различие в параметрах.

Есть два ограничения на перегрузку методов:

• нельзя дважды перегружать методы в разделе Published одного и того же класса;

• для объявления виртуального метода перегружаемым в классе-нас­леднике дополнительно добавляется слово-директива Reintroduce. Синтаксис применения директивы Reintroduce:

Procedure <имя метода>[(<параметры>)]; Reintroduce; Overload;

Type T1=Class

Procedure Test(I: Integer); Overload; Virtual;

End;

// В бачовом классе не обязательно помечать метод как Overload

T2=Class(T1)

Procedure Test(S: String); Reintroduce; Overload;

End;

Begin

SomeObject:=T2.Create;

SonieObject.Test('HeIlo'); // Фактически вызывается Т2.Test

SomeObject.Test(7); // Фактически вызывается Т1.Test

Tl(SomeObject).Test(7); // Можно и так, если известно имя – Т1

По отношению к методам перегрузка позволяет упростить доступ к од­ноименным методам родительского класса, не зная имя класса с одноимен­ным методом.

ж) Дружественные классы.

В языке C++ с помощью ключевого слова friend реализуется концепция дружественных классов, т.е. классов, объектам которых разрешен доступ к Private полям и методам другого класса. В ОР подобного слова нет, однако объекты классов, описанных в одном модуле, имеют взаимный доступ ко всем разделам объектов другого класса. Таким образом фактически реализу­ется дружественность классов в Delphi.