Кто-нибудь знает, в чем разница между перекрытием (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. Перекрытые
методы могут выполняться даже тогда, когда специфический экземпляр класса-предка
является точной копией базового класса. "Замененные" методы могут выполняться
только тогда, когда специфический экземпляр является "слепком" только этого
класса. |