Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
10 Классы испр.doc
Скачиваний:
20
Добавлен:
27.10.2018
Размер:
94.21 Кб
Скачать

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);