Перекрытие виртуальных методов
Кто-нибудь знает, в чем разница между перекрытием (OVERRIDING) виртуального метода и заменой (REPLACING) его? Я немного запутался.
Допустим у вас есть класс:
TMyObject = class (TObject)
|
и его наследник:
TOverrideObject = class (TMyObject)
|
К примеру, TMyObject имеет метод Wiggle:
procedure Wiggle; virtual;
|
а TOverrideObject перекрывает Wiggle:
procedure Wiggle; override;
|
и, естественно, вы реализовали оба метода.
Теперь вы создаете TList, содержащий целую кучу MyObjects и OverrideObjects в
свойстве TList.Items[n]. Свойство Items является указателем, поэтому для вызова
метода Wiggle вам достаточно вызвать необходимый элемент списка. Например так:
if TObject(Items[1]) is TMyObject then
TMyObject(Items[1]).Wiggle
else
if TObject(Items[1]) is TOverrideObject then
TOverrideObject(Items[1]).Wiggle;
|
но возможности полиморфизма и директива override позволяют вам сделать так:
TMyObject(Items[1]).Wiggle;
|
Ваше приложение посмотрит на экземпляр специфического объекта, ссылка на
который содержится в Items[1] и скажет: "Да, это - TMyObject, но, точнее говоря,
это TOverrideObject; но поскольку метод Wiggle является виртуальным методом и
TOverrideObject переопределил метод Wiggle, я собираюсь выполнить метод
TOverrideObject.Wiggle, а не метод TMyObject.Wiggle."
Теперь представьте себе, что при декларации метода вы пропустили директиву
override, попробуйте это выполнить теперь:
TMyObject(Items[1]).Wiggle;
|
Приложение и в этом случае должно "видеть" данный метод, даже если Items[1] -
TOverrideObject; но у него отсутствует перекрытая версия метода Wiggle, поэтому
приложение выполнит TMyObject.Wiggle, а не TOverrideObject.Wiggle (поведение,
которое вы можете как хотеть, так и избегать).
Так, перекрытый метод функционально может отличаться от декларированного
метода, содержащего директиву virtual (или dynamic) в базовом классе, и
объявленный с директивой override в классе-наследнике. Для замены метода
необходимо объявить его в классе-наследнике без директивы override. Перекрытые
методы могут выполняться даже тогда, когда специфический экземпляр класса-предка
является точной копией базового класса. "Замененные" методы могут выполняться
только тогда, когда специфический экземпляр является "слепком" только этого
класса.
|