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