<<
>>

Лекция 3.3. Методы

Методы предназначены для манипулирования данными, входящими в состав класса. Фактически методы представляют собой обычные процедуры и функции, которым разрешен доступ ко всем полям класса.

Методы объявляются в описании класса после объявления полей. Существует несколько типов методов, различающихся по механизму наследования:

· статические

· виртуальные

· динамические

Перекрытие или переопределение методов

Если в классе-потомке объявляются методы, имена которых совпадают с именами методов в родительском классе, то говорят, что эти методы перекрываются. Статические методы, при переопределении, полностью перекрываются в классе-потомке. При этом можно изменять количество и типы параметров в заголовке метода.

При перекрытии виртуальных и динамических методов требуется сохранять количество и тип параметров в заголовках методов.

Перекрываемый метод из родительского класса может быть вызван внутри методов класса-потомка. Для этого используется специальная директива inherited (см. пример реализации метода Area - «Наследование»).

Статические методы

Статические методы при их переопределении в классах-потомках полностью перекрываются, что позволяет полностью изменить объявление метода. По умолчанию все методы считаются статическими. Адреса статических методов определяются на этапе компиляции. Вызываемый метод определяется типом объявленной объектной переменной, а не типом объекта, фактически записанным в переменную, поэтому статические методы не позволяют реализовать концепцию полиморфизма.

Виртуальные и динамические методы

При обращении к виртуальным и динамическим методам вызываемая процедура или функция определяется только в момент обращения. Такой механизм называется поздним связыванием. Виртуальные и динамические методы определяются по типу фактической объектной переменной. Именно виртуальные и динамические методы позволяют в полной мере реализовать концепцию полиморфизма.

При объявлении виртуальных и динамических методов используются директивы virtual и dynamic соответственно. Виртуальные и динамические методы различаются только внутренней реализацией. Кратко опишем их внутренние различия:

При вызове метода адрес метода определяется из таблиц VMT (Virtual Method Table) – для виртуальных или DMT (Dynamic Method Table) – для динамических. Таблицы VMT охватывают виртуальные методы всей иерархии классов, а DMT содержит информацию только о динамических методах текущего класса, следовательно, таблица VMT больше чем DMT. Так как адреса всех виртуальных методов содержаться в одной таблице VMT, то поиск адреса требуемого метода выполняется быстро. При вызове динамического метода адрес кода его реализации сначала ищется в DMT экземпляра и если адрес не найден, то в таблицах DMT всех классов-предков в порядке иерархии, что значительно медленней, чем у виртуальных методов. Следовательно, виртуальные методы выполняются быстрее, чем динамические, но требуют значительно больше памяти.

Для того чтобы изменить поведение виртуальных или динамических методов у потомка (переопределить метод или перекрыть) используется служебное слово override.

Рассмотрим использование виртуальных методов для реализации концепции полиморфизма, на основе классов TCircle и TRing. Объявим методы класса «окружность», которые переопределяются в классе «кольцо», как виртуальные:

Type

TCircle = class

private

FХ, FY: Real;

FR: Real;

public

function Area: Real; virtual;

function Circumference: Real;

function Inside(X, Y: Real): Real; virtual;

end;

TRing = class (TCircle)

private

FR2: Real;

public

function Area: Real; override;

function Circumference2: Real;

function Inside(X, Y: Real): Boolean; override;

end;

При таком определении эти классы являются полиморфными. Для упрощения, в примере пропущено описание свойств и некоторых методов.

Пример использования полиморфизма:

var C: TCircle;

R: TRing;

C:= R;

C.Area;, результат вычисления - площадь кольца, если бы методы были статическими, то результат определялся бы типом объявленной объектной переменной TCircle, а не фактическому значению и был бы равен площади окружности.

Абстрактные методы

В начале процесса создания иерархии классов, как правило, известны имена методов и, естественно, их назначение, однако конкретный код будет определяться в дочерних классах. В этом случае удобно, в базовом классе, создать интерфейсы методов без конкретной реализации. Для подобных целей используются абстрактные методы.

Абстрактные методы определяются в классе, но не имеют кода реализации, считается, что конкретный код должен быть реализован в дочерних классах. Для объявления абстрактного метода используется директива abstract. Поскольку абстрактные методы обязательно должны быть переопределены, то абстрактными можно объявлять только виртуальные и динамические методы. Попытка вызвать абстрактный метод приведет к возникновению ошибки EAbstractError.

Пример: класс «окружность» может быть создан на основе класса «точка». Для объекта «точка» методы определения площади и длины не имеют никакого смысла. Однако данные методы можно описать в классе TPoint как абстрактные, при этом будет удобнее использовать его в качестве базового типа, совместимого со всеми дочерними типами.

type

TPoint = class

private

FX, FY: Real;

protected // для предотвращения их использования мы сделали их

// защищенными, а после

function Area: Real; virtual; abstract; // их переопределения они

// станут открытыми

function Circumference: Real; virtual; abstract;

// (повысим обл. видимости)

public

function Inside(X, Y: Real): Real; virtual;

end;

TCircle = class (TPoint)

private

FR: Real;

public // повысили область видимости методов Area и Circumference

function Area: Real; override;

function Circumference: Real; override;

function Inside(X, Y: Real): Real; override;

end;

Для упрощения, в примере пропущено описание свойств и некоторых методов.

Перегружаемые методы

В Object Pascal допускается определение в одном классе нескольких методов с одинаковыми именами, но разными списками параметров.

Такие методы называются перегружаемыми, они объявляются при помощи директивы overload. С их помощью можно присваивать одинаковые имена родственным методам. Выбор конкретной версии метода, применимой в данных обстоятельствах, осуществляется компилятором.

Пример: пусть требуется в рамках класса реализовать ряд методов преобразования данных различных типов в строку, тогда интерфейс родственных методов может выглядеть так:

public

function DataToStr(Value: Boolean): String; overload;

function DataToStr(Value: TDate): String; overload;

function DataToStr(Value: TMyType): String; overload;

В результате метод будет выбираться по типу фактического параметра.

Конструкторы и деструкторы

Переменные объектного типа в Object Pascal, в действительности, являются указателями, то есть ссылкой на область памяти, в которой размещается объект. Причем ресурсы под объект выделяются динамически, т.е. объявив переменную объектного типа (var Circle: TCircle), мы не создали сам объект. Поэтому перед использованием объекта необходимо выполнить его инициализацию – выделить необходимую память под объект. Для инициализации объекта используются специальные методы, называемые конструкторами. Для объявления конструктора используется специальное зарезервированное слово constructor. Как правило, конструктор имеет имя Create. По завершении работы с объектом следует освободить занятые им ресурсы. Для этого используется деструктор. Для объявления деструктора используется зарезервированное слово destructor. Как правило, деструктор имеет имя Destroy.

var Circle: TCircle; // объявляем объектную переменную

begin

Circle:= TCircle.Create; // создаем объект

… // работаем с объектом «окружность»

Circle.Destroy; // уничтожаем объект

end;

Вопросы для самоконтроля

1. Как методы различаются по механизму наследования?

2. Почему статические методы не позволяют реализовать концепцию полиморфизма?

3. В чем отличие виртуальных и динамических методов?

4. Какие директивы используются при объявлении методов?

5. В чем назначение перегружаемых методов?

6. В чем назначение конструкторов и деструкторов?

<< | >>
Источник: РазработкА и эксплуатациЯ автоматизированных информационных систем. ЛЕКЦИИ.

Еще по теме Лекция 3.3. Методы:

  1. 5. Оценка эфективности наружной рекламы
  2. ИЗМЕНЕНИЯ В ФОНЕТИЧЕСКОЙ СИСТЕМЕ ДРЕВНЕРУССКОГО ЯЗЫКА, ВЫЗВАННЫЕ РАЗВИТИЕМ СОГЛАСНЫХ ВТОРИЧНОГО СМЯГЧЕНИЯ
  3. Монархическая форма правления.
  4. Унитарное государство.
  5. Конфедерация и иные формы межгосударственных объединений (союзы, сообщества, содружества, ассоциации)
  6. Понятие и классификация функций государства.
  7. Государственные аппарат (бюрократия). Принципы его организации и деятельности.
  8. Органы законодательной власти: порядок образования, структура, компетенция.
  9. Органы судебной власти: порядок образования, структура, компетенция.
  10. Государство в политической системе общества.
  11. 56 Отличительные особенности основных правовых семей мира: романо-германская, англосаксонская, религиозная, обычная (традиционная) группы национальных правовых систем.