- •Объектно-ориентированное программирование
- •Часть 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;
Var TmpFrm: tForm;
Begin
TmpFrm:=TForm.Create(Self); // Вызов метода с описателем - через точку
End;
Примечание:
• Если вызвать конструктор от имени объекта, то новый объект не будет создан (память не выделяется), но будут выполнены операторы, указанные в коде конструктора.
• Конструктор может также вызываться с помощью переменной типа указателя на класс.
ж) Вызов деструкторов
Деструкторы вызываются точно так же, как и большинство других методов класса - через его действующий экземпляр. Синтаксис вызова конструктора следующий:
<имя объекта>.<имя деструктора>[(<параметры>)];
Примечания:
• После вызова деструктора объект становится недоступен и единственная возможная операция, которую можно выполнить - это вызвать конструктор для создания нового экземпляра. Целесообразно присваивать объекту значение Nil сразу после его уничтожения, чтобы в дальнейшем можно было бы проверить его существование.
• Не следует вызывать деструкторы непосредственно. Вызов метода Free, наследуемого от TObject.Free, сравнивает указатель экземпляра со значением Nil перед тем, как вызвать деструктор Destroy.
з) Вызовы конструкторов и деструкторов компонентов Delphi. Любой компонент, попавший в ваше приложение при визуальном проектировании, включается в определенную иерархию объектов, которая замыкается на форме (класс TFonn). Поэтому вызов конструкторов и деструкторов всех компонентов формы производится автоматически при инициализации и удалении формы, незримо для программиста. Сами формы создаются и уничтожаются приложением - глобальным объектом с именем Application. В файле-проекте с расширением *.Dpr можно увидеть вызов конструктора формы в виде строки:
Application.CreateForm(TForml, Fonnl);
и) Динамическое создание объектов. Пользователь может создать объект и программным путем:
Var Mem: tMemo;
Begin
Mem:=TMemo.Create(Self); // Создание экземпляра класса TMemo
Mem.Parent:=Self; // Form1 указывать не обязательно
Mem.Name:='TmpMem'; // Присвоение имени компоненту
FindComponent('TmpMem').Free; // Удаление компонента
2.3. Классовые процедуры и функции
Наиболее важное отличие классовых методов от обычных заключается в том, что при их вызове не требуется экземпляр класса, вследствие чего невозможно и обращение к его полям. Классовые методы - это обычные подпрограммы.
а) Синтаксис объявления классовых методов:
Type <имя клacca>=Class[(<имя родительского класса>)]
. . .
Class Procedure <имя процедуры>[(<параметры>)};
Class Function <имя функции>[(<параметры>)]:<тип результата>
. . .
End;
Примечания:
• В классе может быть объявлено несколько классовых методов.
• Каждое объявление классового метода должно начинаться с зарезервированного слова Class, за которым следует объявление процедуры или функций по обычным правилам.
• Фактически классовые методы ничем не отличаются от обычных процедур и функций. Классовые методы - это лишь удобная возможность указать, что данный метод логически относится к данному классу.
• Реализация классового метода не должна зависеть от состояния любого поля класса во время выполнения. Поля экземпляра класса недоступны для этих методов.
• Классовые методы могут быть виртуальными, при этом их можно переопределять и использовать полиморфизм.
• Одно из назначений классовых методов заключается в возможности извлечения данных о классе из структуры RTTI. Важнейшие из них определены в самом классе TObject: имя класса (ClassName), размер экземпляра (InstanceSize), адреса (MethodAddress) и имена методов (MethodName), указатель на класс-предок (ClassParent) и указатель (Classlnfo) на структуру PTypelnfo, позволяющую извлекать всю информацию о классе из структуры (RTTI) и другие.