Главная/Раздел  5

 

 

Главная

 

 Раздел 1

 

Раздел 2

 

Раздел 3

 

Раздел 4

 

Раздел 5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Объектно-ориентированное программирование.
Виртуальные методы. Конструкторы и деструкторы

Виртуальные методы.

Для того, чтобы определить виртуальный метод, необходимо указать после его заголовка в объектовом типе служебное слово virtual. При этом во всех потомках объектового типа одноименные (переопределяющие) методы должны также специфироваться как виртуальные; кроме того, все они должны иметь точно такой же набор формальных параметров, что и самый первый виртуальный метод. Turbo Pascal обеспечивает вызов в процессе выполнения программы именно того виртуального метода, который определён для вызывающего объекта. Таким образом, ОДИН И ТОТ ЖЕ метод будет работать ПО РАЗНОМУ (передвигать различные фигуры) в зависимости от того, какой объект этот метод вызывает. Такое свойство называется полиморфизмом и предоставляет весьма широкие возможности при разработке программ. Имея некоторую совокупность "базовых" объектов, программист может произвольно наращивать их номенклатуру применительно к своим требованиям, причём новые объекты будут по-своему использовать одни и те же базовые методы. Работа с виртуальными методами будет происходить немного медлен- нее, чем с обычными (статическими) методами; кроме того, виртуальные методы приводят к дополнительному расходу оперативной памяти. Однако эти издержки весьма невелики и не должны служить препятствием для использования виртуальных методов.

Конструкторы и деструкторы.
Динамические объекты.

Корректная работа с виртуальными методами требует соблюдения ещ/ одного правила. Если объектовый тип содержит виртуальный метод, то он обязательно должен также содержать хотя бы один особый метод, называемый конструктором; этот метод может быть как определён в самом объекте, так и унаследован от объекта-предка. Метод-конструктор должен быть применён к экземпляру объекта до первого вызова виртуального метода. На практике в качестве конструктора определяют метод, который устанавливает некоторые начальные значения экземпляра объекта. Следует помнить, что каждый отдельный экземпляр объекта должен быть инициализирован отдельным вызовом конструктора. Синтаксически конструктор оформляется в точности как обычный метод-процедура, с заменой служебного слова procedure на служебное слово constructor. Смысл введения конструкторов заключается в том, что он помимо действий, заданных в его теле, формирует в экземпляре объекта необходимую информацию для последующих вызовов виртуальных методов объекта. В одном объектовом типе может быть любое число конструкторов. Сам конструктор не может быть виртуальным. Несоблюдение приведенного правила, хотя и не контролируется компилятором, но при выполнении может привести к непредсказуемому поведению программы. Ранее уже говорилось, что значения (экземпляры) объектовых типов, так же, как и значения любых других типов, могут быть определены в программе либо посредством описаний, либо динамически, с использованием стандартной процедуры New. Последний способ образования объектов на практике применяется значительно чаще. Следующий фрагмент программы демонстрирует технику динамического порождения и инициализации объектов:

     var
        CitclePtr: ^Circle;
     begin
       New(CirclePtr);
       CirclePtr^.Create(100,200,35);
     .  .  .

Даный пример показывает, что способ динамического образования экземпляров объектов ничем не отличается от порождения значений любых других типов. Нужно ещё заметить следующее. Как уже говорилось, если объект содержит виртуальные методы, к его экземпляру должен быть применён соответствующий конструктор (это действие и показано в последнем операторе фрагмента). Таким образом, порождение объекта и его инициализация конструктором являются теми действиями, которые совершаются последовательно. В целях большей наглядности Turbo Pascal допускает совмещение этих двух действий в одном вызове New: если первым параметром стандартной процедуры New является указатель на объектовый тип, то вторым параметром процедуры может являться вызов его конструктора, например:

     New(CirclePtr,Create(100,200,35));

Обратите внимание, что вызов конструктора в последнем случае не содержит составного (точечного) имени, так как первый параметр New однозначно определяет, из какого объектового типа берётся конструктор Create. Освобождение динамической памяти, выделенной объекту, реализуется стандартной процедурой Dispose, также аналогично значениям других типов:

     Dispose(PointPtr);

С процедурой освобождения памяти связан особый вид методов, в некотором смысле симметричный методам-конструкторам. Эти методы называются деструкторами и предназначены для выполнения каких-либо действий завершающего характера. Деструкторы оформляются так же, как обычные методы-процедуры, с заменой служебного слова procedure на служебное слово destructor. В отличии от методов-конструкторов, деструкторы могут быть виртуальными и могут наследоваться; в одном объектовом типе может быть определено несколько деструкторов. Использование деструкторов реально необходимо в случае, когда экземпляр объекта был создан динамически (процедурой New). Тогда завершение работы с данным экземпляром рекомендуется производить посредством расширенного вида процедуры Dispose, вторым параметром которой является вызов деструктора. Например, если PointPtr - указатель на экземпляр объектового типа Point, a Point.Done - деструктор этого типа, то можно совместить операцию освобождения памяти и завершающие действия с экземпляром:

     Dispose (PointPtr,Done);

Заметим, что вызов деструктора как такового (вне процедуры Dispose) не приведёт к освобождению памяти, занимаемую экземпляром объекта. Необходимость введения деструкторов вызывается следующим обстоятельством. Предположим, что имеются указатели на два экземпляра объектов, один из которых имеет родительский тип, другой - тип потомок:

     PointPtr
     CirclePtr

По правилам совместимости допустимо присваивание вида:

     PointPtr := CirclePtr;

После такого присваивания указатель PointPtr содержит ссылку на область большего размера, нежели память, отводимая для экземпляров типа Point. В данной ситуации применение к указателю PointPtr стандартной процедуры Dispose с методом-деструктором в качестве второго параметра гарантирует корректное освобождение именно того объёма памяти, который реально занимает экземпляр по указателю PointPtr.

Ограничение области видимости компонентов

Часть полей и методов объектовых типов можно объявить как скрытые. Смысл введения скрытых компонент объектов заключается в ограничении области видимости идентификаторов этих компонент. Для этого используется служебное слово private, которое используется по следующей схеме:

     type
       ObjectType = object
                      обычные поля и методы
                    private
                      скрытые поля и методы
                    end.

Идентификаторы полей и методов, объявленных как скрытые, считаются известными (доступными, видимыми) ТОЛЬКО в пределах программы или модуля, в которой (в котором) содержится описание данного объектового типа. Вне модуля, содержащего такое описание (например, в программе, использующей этот модуль), скрытые компоненты объектового типа неизвестны и недоступны, в то время как сам объектовый тип и его остальные компоненты считаются известными по обычным правилам.

Введение понятия скрытых компонент объектовых типов придаёт объектам дополнительное сходство с модулями; в этом смысле список скрытых компонент аналогичен разделу реализации модуля. Это позволяет изолировать технические подробности реализации объектов от программ-потребителей, что способствует большей независимости программных единиц и служит добавочным средством контроля за исполнением объектов.

Контрольные вопросы.

  1. В каких случаях используются виртуальные методы?
  2. Какие методы называют конструкторами?
  3. Какие методы называют деструкторами?
  4. Как регулируется область доступности (видимость) компонентов объекта?

НАЗАД               

 

 

 

 

 

 

 

 

 :::

 

 :::

 

 

 

 

 

 

 

Сайт создан в системе uCoz