- •Объектно-ориентированное программирование
- •Часть 1 классы и объекты
- •Введение
- •1. Классы и объекты
- •Var aLine: tLine;
- •Var aColorLine: tColorLine;
- •2. Методы
- •2.1. Методы-функции и методы-процедуры
- •2.2. Конструкторы и деструкторы
- •Inherited Create;
- •Var TmpFrm: tForm;
- •Var Mem: tMemo;
- •2.3. Классовые процедуры и функции
- •Var s: String;
- •2.4. Скрытый Self
- •3. Видимость компонентов класса
- •4. Наследование
- •4.1. Основные понятия
- •4.2. Наследование полей
- •4.3. Поведение методов при наследовании
- •Var SomeObject: t1;
- •Virtual;
- •Virtual; Abstract;
- •4.4. Иерархия классов
- •4.5. Rtti
- •4.6. Проверка типа
- •4.7. Приведение типа
- •4.8. Указатели на класс
- •Var ObjRef: tObjRef;
- •Implementation
- •X, y, w, h: Integer): tControl;
- •5. Полиморфизм
- •6. Свойства (properties)
- •6.1. Объявление свойств
- •6.2. Объявления свойств-массивов
- •Var I: Byte;
- •6.3. Раздел Read
- •6.4. Раздел Write
- •Inherited Create;
- •Inherited Destroy;
- •6.5. Команды Default, NoDefault и Stored
- •6.6. Команда Index
- •Var aYear, aMonth, aDay: Word;
- •Var aYear, aMonth, aDay: Word;
- •6.7. Команды DispId и Implements
- •6.8. Переопределение свойств при наследовании
- •7. События (events)
- •7.1. Объявление событий
- •IfAssigned(fOnMouseMove) Then fOnMouseMove(Self, Shift, X, y);
- •Vk_return: NumMemo.DoNumStr(l);
- •Vk_return: PostMessage(NumMemo.Handle, wm_user1,1, 0);
- •7.2. Обработчики событий
- •7.3. Делегирование событий
- •Var Objl: tIstClass;
- •7.4. Переопределение стандартных событий
- •Var NewBtn: tNewButton;
4.4. Иерархия классов
По мере добавления свойств и методов классы становятся все более специализированными. Начало иерархии классов Delphi, взятое из справочной системы, приведено на следующем рисунке.
Последовательность добавления особенностей в классы можно проследить на примере визуального класса, реализующего кнопки управления. Эта иерархия классов представлена на следующем рисунке.
На каждом уровне иерархии добавляются важные возможности для класса:
• TObiect - Включает более 25 методов, общих для всех объектов (17 Delphi 1).
» TPersistent - Добавляет возможность писать самого себя в ЕХЕ файл во время компиляции и переносить себя обратно из ЕХЕ файла во время выполнения.
• TComponent - Вводит имя компонента (Name), множество состояний объекта (чтение, запись, выборка и т.п.), указатель на владельца (Owner), обеспечивает возможность создания компонентов во время выполнения программы с соответствующей регистрацией компонентов в списке.
• TControl - Добавляет возможность взаимодействия с пользователем.
• TWinControl - Добавляет возможность использовать механизмы Windows для создания окон.
• TButtonControl - Обеспечивает работу с кнопками.
• TButton - Реализует "реальные" кнопки с конкретными возможностями: изменение поверхности, опускание кнопки и т.п.
4.5. Rtti
Переменная типа класса представляет собой 4-х байтный указатель на экземпляр класса, который и является объектом. Внутренний формат данных объекта похож на запись. Каждый экземпляр класса содержит отдельную копию его полей. Поля, как уже указывалось, располагаются в порядке объявления, начиная с предков. Рассмотрим внутреннюю структуру объекта, которая приведена на следующем рисунке.
• Первое поле каждого экземпляра класса хранит указатель на свой класс, точнее на начало специальной 76-байтной структуры (Delphi 5), называемой RTTI (Run-Time Type Information) - генерируемой транслятором описание класса, содержащее информацию времени выполнения о типе. RTTI предоставляет приложениям Delphi возможность получения информации об объектах непосредственно во время выполнения программы. Формат RTTI -это запись, поля которой приведены в табл.1. В RTTI содержатся данные, полностью характеризующие класс, а класс TObject включает несколько методов, предназначенных для получения информации о конкретном экземпляре объекта: его имя (ClassName), размер экземпляра (InstanceSize), указатели на класс-предок (ClassParent), тип класса (ClassType) т.п. Одно из полей (со смещением -76) содержит адрес VMT, а другое (со смещением -48) – адрес DMT.
• Адреса виртуальных методов в VMT расположены последовательно, в порядке объявления методов в иерархии класса. Первоначально располагаются адреса методов, объявленных в текущем классе, а затем унаследованных. Адреса переопределенных методов также включаются в VMT, что обеспечивает возможность применения директивы Inherited.
• Адреса динамических методов, объявленных в данном классе, имеют отрицательные индексы (смещения) относительно таблицы VMT. Таблица DMT хранит адреса только тех методов, которые объявлены в данном классе.
• После указателя на класс располагаются поля данных класса, начиная с предков. Последними располагаются поля данных текущего класса. Генерирование информации для RTTI осуществляется с ключом $М+. RTTI играет самостоятельную важную роль и может использоваться явно и неявно. В ОР определены два оператора Is и As, неявно использующие RTTI.
Таблица 1
Смещ
|
Тип
|
Константа
|
Описание
|
-76
|
Pointer
|
vmtSelfPtr
|
Указатель на таблицу VMT (или Nil)
|
-72
|
Pointer
|
vmtIntfTable
|
Указатель на таблицу интерфейсов (или Nil)
|
-68
|
Pointer
|
vmtAutoTable
|
Указатель на таблицу информации об Automation (или Nil)
|
-64
|
Pointer
|
vmtInitTable
|
Указатель на таблицу инициализации (или Nil)
|
-60
|
Pointer
|
vmtTypeInfo
|
Указатель на таблицу информации о типе (или Nil)
|
-56
|
Pointer
|
vmtFieldTable
|
Указатель на таблицу определения полей (илиNil)
|
-52
|
Pointer
|
vmtMethodTable
|
Указатель на таблицу определения статических методов (или Nil)
|
-48
|
Pointer
|
vmtDynainicTable
|
Указатель на DMT (или Nil)
|
-44
|
Pointer
|
vmtClassName
|
Указатель на строку с именем класса
|
-40
|
Cardinal
|
vmtInstanceSize
|
Размер экземпляра в байтах
|
-36
|
Pointer
|
vmtParent
|
Указатель на родительский класс (или Nil)
|
-32
|
Pointer
|
vmtSafecalIException
|
Указатель на метод SafecallException (или Nil)
|
-28
|
Pointer
|
vmtAfterConstruction
|
Адрес метода AfterConstruction
|
-24
|
Pointer
|
vmtBeforeDestruction
|
Адрес метода BefbreDestruction
|
-20
|
Pointer
|
vmtDispatch
|
Адрес метода Dispatch
|
-16
|
Pointer
|
vmtDefaultHandler
|
Адрес метода DefaultHandler
|
-12
|
Pointer
|
vmtNewInstance
|
Адрес метода Newlnstance
|
-8
|
Pointer
|
vmtFreeInstance
|
Адрес метода Freelnstance
|
-4
|
Pointer
|
vmtDestroy
|
Адрес деструктора Destroy
|
0
|
Pointer
|
vmtQuery Interface
|
Адрес метода Querylnterface
|
4
|
Pointer
|
vmtAddRef
|
Адрес метода AddRef
|
8
|
Pointer
|
vmtRelease
|
Адрес метода Release
|
12
|
Pointer
|
vmtCreateObject
|
Адрес метода CreateComObject
|