- •1. Основные понятия объектно-ориентированного программирования
- •2. Определение класса. Инкапсуляция. Синтаксис и программирование свойств
- •2.1. Поля
- •2.2. Свойства
- •3. Методы
- •4. Наследование
- •5. Полиморфизм
- •6. Создание и уничтожение объектов. Конструкторы. Деструкторы
- •7. Области видимости
- •8. Динамическая информация о типе. Оператор Is и оператор As
5. Полиморфизм
Полиморфизм — это возможность определения единого по имени действия (метода в виде процедуры или функции), применимого ко всем объектам иерархии наследования, т. е. возможность иметь несколько методов с одним и тем же, именем для различных объектов одной иерархии. Это средство для развития объектов в потомках. Оно реализуется тем, что объект-потомок может добавлять и переопределять методы, т. е. заменять методы предка на новые с теми же именами. Какой из методов будет выполняться при обращении к методу с заданным именем, определяется типом объекта (предок или потомок) и используемого метода (статический, виртуальный или динамический).
Чтобы смоделировать совокупность явлений или процессов средствами ООП, надо выделить их самые общие, типовые черты. Элементы процесса, общие для, всей совокупности, должны быть реализованы в виде статических методов. Тев) которые варьируются при переходе от общего к частному, лучше выполнить в виде виртуальных методов. Основные, «родовые» черты (в том числе методы) надо определить в классе-предке и затем перекрывать их при необходимости в классах-потомках.
6. Создание и уничтожение объектов. Конструкторы. Деструкторы
Так как Delphi использует только динамические объекты, переменная классового типа - это указатель на экземпляр класса. Она должна быть инициализирована во время выполнения программы вызовом конструктора. В результате его выполнения экземпляру класса выделяется ОП (оперативная память) в куче, а переменная классового типа получает значение адреса размещения конкретного экземпляра (объекта), который можно использовать в программе.
Windows автоматически представляет все типы ОП ПК в виде единого адресного пространства: основную, расширенную (Extended) и дополнительную (Expanded). Поэтому при работе с Delphi для объектов и других динамических переменных доступна вся ОП ПК.
Новый экземпляр класса создается и уничтожается специальными методами -конструктором и деструктором. Им принято давать имена Create и Destroy соответственно. Тексты методов конструктора и деструктора располагаются, как и всех других методов, в разделе Implementation.
Конструктор - это специальный вид подпрограммы. В его заголовке стоит слово Constructor. Конструктор может включать инициализацию (присваивание) значений всем или некоторым полям объекта, запрос ОП динамическим переменным, открытие файлов и т. д. При вызове конструктора создается VMT -таблица виртуальных методов.
Деструктор - это специальная процедура, предназначенная для уничтожения экземпляра класса и освобождения ОП, которая была выделена при выполнении конструктора. Деструктор размещается вместе с другими методами класса при определении типа и оформляется так же, как обычный метод-процедура, но слово Procedure заменяется словом Destructor.
В теле конструктора не требуются операторы для создания экземпляра класса. Это происходит автоматически, до выполнения его первого оператора begin. Назначение кода внутри конструктора - инициализировать только что созданный экземпляр объекта.
Транслятор инициализирует все поля экземпляра класса (в отличие от Pascal). Все числовые поля инициализируются нулем, а нечисловые - пустой строкой, значениями nil или False. Но считается правилом хорошего тона в конструкторе инициализировать все поля явно, присвоив им начальные значения. Если нет операторов инициализации, тело конструктора может быть пустым. Если в классе-потомке нет новых полей, конструктор в нем можно не создавать. А для создания экземпляра объекта надо вызвать конструктор предка.
Чтобы правильно проинициализировать в создаваемом объекте поля, относящиеся к классу-предку, надо сразу после входа в конструктор вызвать конструктор предка. Например:
Constructor TMyObject.Create;
begin
inherited Create; // - вызов конструктора предка;
end;
Деструктор вызывается тогда, когда работа с данным экземпляром класса закончена. В одном классе может быть несколько деструкторов, но чаще он один. Если к классу надо добавить операции для освобождения динамической ОП, надо оформить свой деструктор.
После вызова деструктора переменная экземпляра класса становится неопределенной. Но ее значение (указатель) не устанавливается в Nil. Можно после уничтожения переменной типа Class сразу присвоить ей значение Nil. Впоследствии можно определить, есть ли такой экземпляр объекта. Если вызвать деструктор для переменной, которая установлена в Nil, возникает ошибка - нарушение общей защиты (General Protection Fault, GPF). Чтобы уничтожить экземпляр класса, можно использовать метод Free. Он дополнительно проверяет переменную на Nil, предотвращая вызов деструктора для указателя - переменной, значение которой равно Nil, и возникновение GPF.
Оформление текста деструктора аналогично оформлению текстов обычных методов. Деструктор может содержать освобождение ОП, выделенной динамическим переменным, закрытие файлов и пр. В теле деструктора не нужны специальные операторы для освобождения ОП экземпляра класса. Это производится автоматически. Поэтому тело деструктора может быть пустым. В случае, если объект не создает и не включает в себя никаких подчиненных объектов и динамических переменных, деструктор потомка не нужен. А для уничтожения экземпляра класса вызывается деструктор предка.
Если сформирован собственный деструктор, то для того чтобы правильно освободить ОП экземпляра-предка, надо из него вызвать деструктор предка. Например:
Destructor TMyObject.Destroy;
begin
inherited Destroy; // - вызов деструктора предка;
end;
Любой компонент, используемый в приложении при визуальном проектировании в Delphi, включается в определенную иерархию объектов. Эта иерархия замыкается на форме. Для всех ее составных частей (объектов) конструкторы и деструкторы вызываются автоматически, в процессе выполнения программы.
Это реализует в приложении глобальный объект Application. В файле проекта виден явный вызов метода только для создания формы. Например:
Application.CreateForm(TMainForm, MainForm);