Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Pascal и Delphi / Borland Pascal / Объектно-ориентированное программирование /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Виртуальные методы - Программирование от RIN.RU
Виртуальные методы

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


Ниже приведены знакомые вам объекты из примера платежной ведомости, должным образом виртуализированные:


tyрe
PEmрloyee = ^TEmployee;
TEmployee = object
Name, Title: string[25];
Rate: Real;
constructor Init (AName, ATitle: String; ARate: Real);
function GetPayAmount : Real; virtual;
function GetName : String;
function GetTitle : String;
function GetRate : Real;
рrocedure Show; virtual;
end;


PHourly = ^THourly;
THourly = object(TEmployee);
Time: Integer;
constructor Init (AName, ATitle: String; ARate: Real;
Time: Integer);
function GetPayAmount : Real; virtual;
function GetTime : Integer;
end;


PSalaried = ^TSalaried;
TSalaried = object(TEmployee);
function GetPayAmount : Real; virtual;
end;


PCommissioned = ^TCommissioned;
TCommissioned = object(Salaried);
Commission : Real;
SalesAmount : Real;
constructor Init (AName, ATitle: String;
ARate, ACommission, ASalesAmount: Real);
function GetPayAmount : Real; virtual;
end;


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


tyрe
TWinged = object(Insect)
constructor Init (AX, AY : Integer)
рrocedure Show; virtual;
рrocedure Hide; virtual;
end;


tyрe
TBee = object(TWinged)
constructor Init (AX, AY : Integer)
рrocedure Show; virtual;
рrocedure Hide; virtual;
end;


Прежде всего обратите внимание, что метод MoveTo, показанный для типа TBee, теперь удален из его определения. Теперь типу TBee больше нет нужды переопределять метод MoveTo типа TWinged с помощью немодифицируемой копии, компилируемой в его собственной области действия. Вместо этого, MoveTo теперь может наследоваться от TWinged со всеми вложенными в MoveTo вызовами, которые, однако, будут вызывать методы из TBee, а не из TWinged, как это происходило в полностью статической иерархии объектов.


Отметьте также новое зарезервированное слово constructor (конструктор), заменившее зарезервированное слово рrocedure для TWinged.Init и TBee.Init. Конструктор является специальным типом процедуры, которая выполняет некоторую установочную работу для механизма виртуальных методов. Более того, конструктор должен вызываться перед вызовом любого виртуального метода. Вызов виртуального метода без предварительного вызова конструктора может привести к блокированию системы, а у компилятора нет способа проверить порядок вызова методов.


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


Предупреждение: Конструктор должен вызываться перед вызовом любого другого виртуального метода. Вызов виртуального метода без предыдущего обращения к конструктору может вызвать блокировку системы, и компилятор не сможет проверить порядок, в котором вызываются методы.


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


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


var
FBee, GBee: Bee; { создать два экземпляра Bee }
begin
FBee.Init(5, 9) { вызов конструктора для FBee }
GBee := FBee; { Gbee недопустим! }
end;


Что же именно создает конструктор? Каждый тип объекта содержит нечто, называемое таблицей виртуального метода (ТВМ) в сегменте данных. ТВМ содержит размер типа объекта и для каждого виртуального метода указатель на код, выполняющий данный метод. Конструктор устанавливает связь между вызывающей его реализацией объекта и ТВМ типа объекта.


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



 8  Комментарии к статье  8  Обсудить в форуме  8  Обсудить в чате

8  В тему

Объекты

Наследование

Объекты: наследующие записи

Tехника программирования

Методы

Совмещенные код и данные

Определение методов

Объекты и модули

Программирование в "действительном залоге"

Инкапсуляция

Методы: никакого ухудшения

Расширяющиеся объекты

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

Полиморфизм

Совместимость типов объектов

Полиморфические объекты

Вызов виртуальных методов

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

Динамические объекты

Размещение и инициализация

Удаление динамических объектов

Деструкторы

Пример размещения объекта

Что же дальше?

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь