Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Топ:
Выпускная квалификационная работа: Основная часть ВКР, как правило, состоит из двух-трех глав, каждая из которых, в свою очередь...
Процедура выполнения команд. Рабочий цикл процессора: Функционирование процессора в основном состоит из повторяющихся рабочих циклов, каждый из которых соответствует...
Эволюция кровеносной системы позвоночных животных: Биологическая эволюция – необратимый процесс исторического развития живой природы...
Интересное:
Национальное богатство страны и его составляющие: для оценки элементов национального богатства используются...
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Дисциплины:
2018-01-04 | 243 |
5.00
из
|
Заказать работу |
|
|
// Реализация scex методов пример»
После выполнения создания экземпляров объектов: objectl :=TClassl.Create; Ob-iect2:»TClass2. Create;
внутренняя структура объектов эти: классов будет иметь вид, представленный ма рис. 3.6.
На рис. 3.6 наглядно видно, чем сличаются между собой различные методы при хранении в реальных объектах в оперативной памяти. Следует отметить, что в экземпляре объекта хранится адре«того места таблицы виртуальных методов, где хранится адрес первого виртуальяого метода. Служебная информация класса хранится по адресам оперативно! памяти с отрицательным смещением. Указанные смещения описаны в фай;е модуля System: vmtSelfPtr = -76;
vmtintfTable * -72;
vmtAutoTable = -68;
vmtlnitTable = -64;
vmtTypelnfo * -60;
vatFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtlnstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32 deprecated;//don't use those constants.
vmtAfterConstruction = -28 deprecated;//use VMTOFFSET in asm instead
vmtBeforeDestruction = -24 deprecated;
vmtDispatch = -20 deprecated;
vmtDefaultHandler = -16 deprecated;
vmtNewInstance я -12 deprecated;
vmtFreelnstance = -8 deprecated;
vmtDestroy = -4 deprecated;
vmtQuerylnterface = 0 deprecated;
vmtAddRef = 4 deprecated;
vmtRelease = 8 deprecated;
vmtCreateObject = 12 deprecated;
Работать с этими областями оперативной памяти следует осторожно, поскольку информация в них используется Delphi для управления объектами и их экземплярами. При обращении к константам с директивой deprecated компилятор выдает предупреждение.
Правила выбора между виртуальными и динамическими методами. J. Если метод, скорее всего, будет перекрыт всеми потомками, его следует сделать виртуальным.
· Если метод будет перекрываться не очень часто, но все же требует позднего связывания для большей гибкости, то его следует сделать динамическим.
· Если метод будет вызываться очень часто, много раз в секунду, сделайте его виртуальным.
|
· Следует учитывать, что самые быстрые и экономичные - статические методы, которые, правда, не обеспечивают позднего связывания.
Абстрактные методы
Иногда попытка создать иерархию классов путем выделения общих признаков приводит к тому, что образуется класс, методы которого реализовывать бессмысленно. Например, если создать класс ТAnimal, который должен объединять общие свойства всех животных, то в нем необходимо описать метод Voice (голос), поскольку большинство животных могут издавать звуки. Для каждого отдельного животного (объектов дочерних классов TAnimal) этот звук известен и можно, перекрыв метод Voice, определить его реализацию. Однако вызов метода Voice для объекта класса ТAnimal бессмыслен, и. следовательно, его реализация тоже. Тем не менее, формально, компилятор требует, чтобы любой метод, описанный в классе, был бы сеализован. Чтобы исключить создание подобного ненужного кода и были предусметрены абстоактные методы.
Абстрактный метод - это виртуальный или динамический метод, реализация которого не определена в том классе, з котором он объявлен. Предполагается, что этот метод должен быть объявлен в потомках. Объявляется такой метод с помощью ключевого слова abstract.
Пример 3.10. Описание абстрактного класса, type
TAnimal = class public
function Voice: string; virtual; abstract; end;
TDog = class (TAnimal) public
function Voice: string; override; function Eat: string; virtual; end;
TCat = class (TAnimal) public
function Voice: string; override; function Eat: string; virtual;
End; Implementation
Function TDog.Voice: string; begin
Result:= *Гав-гав'; and;
Function TDog.Eat: string; begin
Result:= 'Pedegree'; and;
Function TCat.Voice: string; begin
Result:= 'Мяу-мяу'; •nd;
function TDog.Eat: string;
Begin
Result 'Wiskas';
and;
Обратите внимание, что программисту не надо описывать реализацию
абстрактного метода TAnimal.Voice.
Object Pascal (в отличие от С++) позволяет создавать экземпляры объектов
класса с абстрактными методами, выдавая при этом предупреждение на этапе компиляции. Поскольку абстрактный метод не имеет реализации, то его можно вызывать только в тех потомках, где он перекрыт, иначе возникнет исключительная ситуация времени выполнения EAbstractError. То есть, >ч;пи описать объект абстрактного класса: <гаг
|
My Animal: TAnimal; И создать экземпляр объекта MyAnimal: MyAnimal:= TAnimal.Create;
ro при вызове метода MyAnimal. Voice будет сгенерирована исключительная • и гуация (ошибка), поскольку была попытка вызвать абстрактный метод.
Рассмотрим использование абстрактных методов. Класс TAnimal содержит ииртуальный абстрактный метод Voice. Каждый наследник этого класса
перекрывает этот абстрактный метод, а также определяет новый метод Bat. Разница заключается в возможности применять полиморфизм. Например, пусть в тексте программы выполнено присваивание MyAnimal:= MyDog;
тогда становится возможным вызов MyAnimal. Voice, который реально выполнит код метода TDog. Voice. А вот вызов MyAnimal.Eat будет также невозможен, поскольку у объектов класса TAnimal не предусмотрен метод с таким названием, то есть для метода Eat полиморфизм не действует.
Информация о типах времени выполнения
Рассматривая приведенным выше пример, необходимо отметить, что все-таки существует возможность вызвать метод Eat, используя объект MyAnimal. Правда для этого используется уже не полиморфизм, а информация о типе времени выполнения (RTTI).
Механизм RTTI заключен в двух операциях для работы с объектами: is и as. Операция as фактически осуществляет приведение типа объекта к другому классу, например: MyAnimal as TDog. Данная конструкция возвращает указатель типа TDog на ту область оперативной памяти, где расположен экземпляр объекта MyAnimal. Таким образом, для объекта MyAnimal становится возможным вызов метода класса TDog: (MyAnimal as TDog).Eat
Однако если перед этим не было выполнено присваивание объекту MyAnimal объекта типа TDog, то при таком вызове произойдет ошибка времени выполнения. Чтобы избежать этой исключительной ситуации, можно использовать операцию is, которая возвращает true, если фактический тип объекта соответствует указанному в операции типу класса, иначе false.
if MyAnimal is TDog then
(MyAnimal as TDog).Eat;
Две операции RTTI, is и as, являются чрезвычайно мощными, и их можно рассматривать как стандартные конструкции программирования. Однако использование RTI "I вместо полиморфизма является плохим стилем программирования и приводит к более медленным программам, поскольку для проверки корректности преобразования типов приходится осуществлять обход по всей иерархии классов. Поэтому следует ограничивать их применение некоторыми специальными случаями, когда полиморфизмом не обойтись.
|
§3.9. Перегрузка методов
Перегрузка методов никак не связана с понятием полиморфизм. Она в определенной степени соответствует понятию перегрузка процедур и функций. При перегрузке определяются несколько методов с одним и тем же именем, но разным числом или типом параметров (сигнатурой). Перегрузка нужна, чтобы произвести одинаковые или похожие действия с разнотипными данными. При вызове метода будет вызываться тот метод, список параметров которого соответствует фактическим аргументам.
Перегружен может быть любой метод (статический, виртуальный и динамический). Перегружаемый метод описывается с помощью ключевого слова overload (не путать с override). Для виртуальных методов в этом случае нужно дополнительно использовать ключевое слово reintroduce.
Перегрузка методов может осуществляться как внутри одного класса, так и, в отличие от перегрузки функций, на разных уровнях иерархии. Например, перегружаемые методы внутри одного класса:
TMyObject = class (TObject)
function Test (I: integer): string; overload; function Test (S: string): string; overload;
•nd;
Очевидно, что отличие двух методов состоит в типе передаваемого в метод параметра. Теперь если будет создан объект класса TMyObject, то при вызове метода Test будет вызван тот метод, к которому подойдет тип фактического
Параметра.
Пример перегрузки методов на разных уровнях иерархии: type
Tl = class (TObject)
procedure Te3t (X: Integer); overload;
end;
T2 = class (Tl)
procedure Test (S: String); overload;
end;
SomeObject:=T2.Create;
SomeObje-t.Test ('Hello!'); // вызывается T2.Test SomeObject. Test (7); // вызывается Tl.Test
|
|
Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...
Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...
Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!