Внутренняя структура объекта Obj2




 

 
 

 

 

Первое поле каждого экземпляра объекта содержит указатель на его класс.

Класс как структура состоит из двух частей:

1. Начиная с адреса, на который ссылается указатель на класс, располагается таблица виртуальных методов, которая содержит адреса всех виртуальных методов класса, включая унаследованные от предков. Длина таблиц VMT объектов Оbj1 и Obj2 одинакова – по два элемента (8 байт). Перед таблицей виртуальных методов расположена специальная структура, содержащая дополнительную служебную информацию. В этой структуре содержатся данные, полностью характеризующие класс: его имя, размер экземпляра, указатели на класс-предок и т. д. (на рис. 1 она показана одним блоком).

2. Одно из полей структуры содержит адрес таблицы динамических методов класса (DMT). Таблица имеет следующий формат:

вначале слово, содержащее количество элементов таблицы;

затем – слова, соответствующие индексам методов. Нумерация индексов начинается с (-1) и идет по убывающей.

После индексов идут собственно адреса динамических методов. Обратим внимание, что DMT объекта Оbj1 состоит из двух элементов, Obj2 — из одного, соответствующего перекрытому методу DynaMethod1. В случае вызова Qbj2.DynaMethod2 индекс не будет найден в таблице DMT Obj2, и произойдет обращение к DMT Оbj1. Именно так экономится память при использовании динамических методов.

 

В языке Delphi определены два оператора — is и as, неявно обращающиеся к таблице динамических методов.

Оператор is предназначен для проверки совместимости по присваиванию экземпляра объекта с заданным классом.

Выражение вида:

AnObject is TObjectType

принимает значение True, только если объект AnObject совместим по присваиванию с классом TObjectType, т. е. является объектом этого класса или одного из классов, порожденных от него. Вообще, определенная проверка происходит еще при компиляции – если формально объект и класс несовместимы, то компилятор выдаст ошибку в этом операторе.

Оператор as введен в язык специально для приведения объектных типов. С его помощью можно рассматривать экземпляр объекта как принадлежащий к другому совместимому типу:

with ASomeObject as TAnotherType do...

От стандартного способа приведения типов с помощью конструкции TAnotherType (ASomeObject) использование оператора as отличается наличием проверки на совместимость типов во время выполнения программы (как в операторе is): попытка приведения к несовместимому типу приводит к возникновению исключительной ситуации EInvalidCast.

После применения оператора as сам объект остается неизменным, но вызываются те его методы, которые соответствуют присваиваемому классу.

Очень полезным может быть оператор as в методах-обработчиках событий. Для обеспечения совместимости в 99% случаев источник события Sender имеет тип TObject, хотя в тех же 99% случаев им является форма или другие компоненты. Поэтому, чтобы иметь возможность пользоваться их свойствами, применяют оператор аs:

(Sender as TControl).Caption:= 'Спасибо!;

 

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

if Sender is TEdit {Определение класса компонента}

then with (Sender as TEdit) do begin

end;

 

if ActiveControl is TEdit //Сравнение с классом компонента

if Sender = MenuIteml then ... // Сравнение с именем компонента

else if Sender = MenuItem2 then...

 

События

Событие – это то, что происходит в процессе работы программы. В Delphi определено несколько десятков типовых событий. Рассмотрим, что представляет собой событие с точки зрения Delphi.

Событие – это свойство процедурного типа, и его значением является указатель на некоторый метод. Присвоить такому свойству значение – указать адрес метода, который будет выполняться в момент наступления события. Такие методы называются обработчиками событий.

Метод отличается от обычной процедуры тем, что помимо явно описанных параметров методу всегда неявно передается еще и указатель на вызывающий его объект, который помещается в автоматически определяемую в классе переменную Self. В данном случае идентификатор Self обозначает ссылку на объект, в котором вызывается метод.

Идентификатор Self часто используется, когда необходимо выполнить динамическое создание объекта.

Пример. Отклик формы на щелчок мыши

procedure TForm1.FormMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Var

MyButton: TButton;

Begin

MyButton:=TButton.Create(Self);

MyButton.Parent:= self;

MyButton.Left:=X;

MyButton.Top:=Y;

MyButton.Caption:='Ура!!!';

end;

На странице Events в Инспекторе Объектов отображаются только те свойства компонента, которые имеют тип метода, т.е. события. Тип обработчика события, который ставится в соответствие какому-либо событию, должен иметь тот же тип, что и событие, поэтому тип метода иначе называется типом обработчика события.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-06-03 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: