Полиморфизм, виртуальные методы — КиберПедия 

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

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

Полиморфизм, виртуальные методы

2017-07-01 302
Полиморфизм, виртуальные методы 0.00 из 5.00 0 оценок
Заказать работу

Создадим еще один дочерний объектный тип - потомок объекта TPoint, который будет представлять собой окружность. X и Y соответственно превращаются в координаты центра, и добавляется радиус. Само собой разумеется, придется переопределить методы инициализации, прорисовки и скрытия.

Type TCircle = object(TPoint) R: Word; Procedure Init(InitX, InitY, InitR:Word; InitC:Byte); Procedure Show; Procedure Hide; Procedure Done; end; Procedure TCircle.Init(InitX, InitY, InitR: Word; InitColor: Byte); begin inherited Init(InitX, InitY, InitC); R:= InitR end; Procedure TCircle.Show; begin Graph.SetColor(Clr); Graph.Circle(X, Y, R); Visib:= True end; Procedure TCircle.Hide; begin Graph.SetColor(Graph.GetBkColor); Graph.Circle(X, Y, R); Visib:= False end; Procedure TCircle.Done; begin inherited Done; R:= 0 end;

Таким образом, мы получили два объекта, методы которых Show и Hide делают одно и то же, но разными способами (полиморфизм).

Но вот непредвиденные последствия. Если мы создадим экземпляр этого объекта, проинициализируем его, а затем попытаемся переместить вызовом метода MoveTo, который был унаследован, то переместится точка, а не окружность. Связано это с тем, что при компиляции в машинный код вместо вызова подпрограммы транслятор подставляет адрес точки входа в эту подпрограмму. Это же справедливо и для методов, поэтому при трансляции метода MoveTo объекта TPoint будут подставлены адреса точек входа методов Show и Hide объекта TPoint. Объект же TCircle наследует метод MoveTo, но не переопределяет его. Поэтому при вызове метода MoveTo экземпляром объекта TCircle он, в свою очередь, вызовет методы Show и Hide объекта TPoint, то есть - переместит точку, а не окружность.

Избежать этого можно двумя способами. Во-первых, каждый раз переопределять метод MoveTo, чтобы транслятор всегда компилировал его заново. Однако это не совсем удобно, поскольку эти методы ничем не будут отличаться. Второй способ - объявить методы Show и Hide виртуальными.

При компиляции объекта, содержащего виртуальные методы, создается так называемая таблица виртуальных методов (ТВМ), содержащая адрес точки входа каждого из виртуальных методов, а в месте вызова такого метода ставится ссылка на ТВМ. При обращении к виртуальному методу компьютер сначала "смотрит", экземпляр какого именно объекта обратился к этому методу, затем "ищет" адрес точки входа виртуального метода именно этого объекта и запускает его. Все это происходит уже на этапе выполнения программы и поэтому называется поздним (динамическим) связыванием. Ранним связыванием называется процесс статического связывания методов с реализациями (экземплярами) объектов. Раннее связывание осуществляется на этапе компиляции для всех статических методов. Для объявления виртуального метода используется зарезервированное слово (директива) virtual.

Type

TPoint = object(TLocation)

Clr: Byte; {Цвет}

Visib: Boolean; {Видимость}

Constructor Init (InitX, InitY:Word; InitColor:Byte);

{Переопределяем метод инициализации - добавляем цвет}

Function GetColor: Byte; {Возвращает цвет}

Procedure Show; virtual;

Procedure Hide; virtual;

Procedure IsVisib: Boolean;

Procedure ChangeColor(NewColor: Byte); {Меняет цвет}

Procedure MoveTo(NewX, NewY:Word);

{Перемещает в новую позицию}

Destructor Done; virtual;

end;

 

TCircle = object(TPoint)

R: Word;

Constructor Init(InitX, InitY, InitR: Word; InitC: Byte);

Procedure Show; virtual;

Procedure Hide; virtual;

Destructor Done; virtual;

end;

Объявление виртуального метода в каком-либо родительском объектном типе накладывает следующие ограничения на все его дочерние типы:

  1. все методы дочерних типов, одноименные с виртуальными родительскими, обязаны быть также виртуальными (нельзя переопределить виртуальный метод статическим);
  2. заголовки всех реализаций одного и того же виртуального метода должны быть полностью идентичными, включая количество формальных параметров и их типы;
  3. каждый объектный тип, имеющий виртуальные методы, обязан иметь конструктор.

Обратите внимание на то, что, кроме добавления слова virtual, изменилось и еще кое-что: при объявлении метода Init появилось незнакомое слово constructor, а метод Done превратился в destructor.

Дело в том, что таблица виртуальных методов изначально не содержит конкретных адресов точек входа. Перед использованием любого из виртуальных методов ее надо заполнить. Делает это специальный метод-конструктор. Метод-конструктор - это разновидность метода-процедуры. Синтаксически он отличается только использованием служебного слова constructor вместо procedure. Однако это приводит к тому, что при компиляции к этому методу добавляется так называемый пролог, код которого как раз и "расставляет" в ТВМ правильные адреса виртуальных методов.

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

Что касается другого "хитрого" метода - деструктора, то он не имеет никакого отношения к виртуализации методов, и зачем он нужен, мы расскажем позже. Отметим только, что деструктор в отличие от конструктора вполне может быть виртуальным


Поделиться с друзьями:

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.01 с.