- •Объектно-ориентированное программирование
- •Введение
- •Основные положения объектно-ориентированного программирования
- •Принципы ооп
- •Элементы классов
- •Области видимости
- •Свойства
- •Объекты
- •События. Взаимодействие объектов.
- •Парадигма объектно-ориентированного программирования
- •От структурированного программирования к ооп
- •Основные понятия и принципы ооп
Объекты
Как уже говорилось, объекты (называемые также экземплярами класса) представляют собой сущности, которые могут содержать данные и код. Объекты Delphi предоставляют программисту все основные возможности объектно-ориентированного программирования, такие как наследование, инкапсуляция и полиморфизм.
Объявление и создание объекта
Безусловно, перед тем как использовать объект, следует объявить его класс. В Object Pascal это делается с помощью ключевого слова class. Объявления классов помещаются в раздел объявления типов модуля или программы.
type TFooObject = class;
Только после объявления класса можно делать объявление переменных этого типа (называемых также экземплярами – instance) в разделе var.
var FooObject: TFooObject;
Полностью объект создается с помощью вызова одного из конструкторов (constructor) соответствующего класса. Конструктор отвечает за создание объекта, а также за выделение памяти и необходимую инициализацию полей. Он не только создает объект, но и приводит его в состояние, необходимое для его дальнейшего использования.
Каждый класс содержит по крайней мере один конструктор Create, который может иметь различное количество параметров разного типа – в зависимости от типа объекта. Ниже рассматривается только простейший конструктор Create без параметров.
Необходимо запомнить, что, в отличие от других языков программирования, например C++, конструкторы в языке Object Pascal не вызываются автоматически. Создание каждого объекта с помощью вызова его конструктора входит в обязанности программиста. Синтаксис вызова конструктора следующий.
FooObject:= TFooObject.Create;
Обратите внимание на особенность вызова конструктора – он вызывается с помощью ссылки на класс, а не на экземпляр класса (в отличие от других методов, которые вызываются с помощью ссылки на класс). В этом есть глубокий смысл – ведь экземпляр объекта FooObject в момент вызова конструктора еще не создан.
Но код конструктора класса TFooObject статичен и находится в памяти. Он относится к классу, а не к его экземпляру, поэтому такой вызов вполне корректен. Вызов конструктора для создания экземпляра класса часто называют созданием объекта.
При создании объекта с помощью конструктора компилятор гарантирует, что все поля объекта будут инициализированы. Все числовые поля будут обнулены, указатели примут значение nil, а строки будут пусты.
Уничтожение объекта
По окончании использования экземпляра объекта следует освободить выделенную для него память с помощью метода Free. Этот метод сначала проверяет, не равен ли экземпляр объекта значению Nil, и затем вызывает деструктор (destructor) объекта – метод Destroy.
Понятно, что действие деструктора обратно действию конструктора, т.е. он освобождает всю выделенную память и выполняет другие действия по освобождению захваченных конструктором объекта ресурсов. Синтаксис вызова метода Free прост.
FooObject.Free;
Обратите внимание, что, в отличие от вызова конструктора, вызов деструктора выполняется с помощью ссылки на экземпляр, а не на тип.
Кроме этого, запомните еще один совет: никогда не используйте непосредственный вызов метода Destroy. Более безопасно и корректно вызвать метод Free.
В Object Pascal все экземпляры объекта – динамические, и программист должен удалять их сам. Необходимо уничтожать и все, что было создано в программе. Исключением из этого правила являются объекты, принадлежащие другим объектам. Этот тип объектов уничтожается автоматически. Еще одним исключением являются объекты с управляемым временем жизни, имеющие собственный счетчик ссылок (например, производные от классов TInterfacedObject или TComObject), которые автоматически удаляются после ликвидации последней ссылки на них.
Также необходимо понимать, что нет необходимости всегда объявлять и описывать конструкторы и деструкторы. Ведь все классы языка Object Pascal неявно наследуют функциональные возможности базового класса TObject, причем, независимо от того, указано ли это наследование явно или нет. Например, следующее объявление:
type TFoo = class;
полностью эквивалентно объявлению класса:
type TFoo = class(TObject);
Чтобы правильно инициализировать в создаваемом объекте поля, относящиеся к классу-предку, нужно сразу же при входе в конструктор вызвать конструктор предка при помощи зарезервированного слова inherited:
constructor TMyObject.Create;
begin
inherited Create;
...
end;
Во многих примерах, поставляемых вместе с Delphi, вы почти не увидите там вызовов конструкторов и деструкторов. Дело в том, что любой компонент, попавший при визуальном проектировании в ваше приложение из Палитры компонентов, включается в определенную иерархию. Иерархия эта замыкается на форме (класс TForm): для всех ее составных частей конструкторы и деструкторы вызываются автоматически, незримо для программиста. Кто создает и уничтожает формы? Это делает приложение (глобальный объект с именем Application).
В файле проекта (с расширением dpr) вы можете увидеть вызовы метода Application.CreateForm, предназначенного для этой цели.
Что же касается объектов, создаваемых динамически (во время выполнения приложения), то здесь нужен явный вызов конструктора и метода Free.