Delphi - 向下转换对象不调用基本方法

时间:2015-09-22 08:15:14

标签: delphi override virtual downcast

我有一个基础对象类型:TBServiceBookings然后我从那里派生出另一个对象类型:TBServiceQuotes

因此,当我的表单被创建时,我决定使用哪个对象。在这个例子中,我创建了派生对象。

if fScreenType = ST_NewAppointment then
  fBookingObject :=   TBServiceBookings.CreateServiceBookings(nil,botSingle)
else
  fBookingObject  := TBServiceQuotes.CreateServiceQuotes(nil,botSingle);

在某些阶段,我只想调用基类的方法。所以我将派生对象转换为基类型并调用它的方法,但它继续使用派生方法 - 这是我不想要的。

我试过了:

1)  fBookingObject := TBServiceBookings(fBookingObject);
    fBookingObject.SetupNewAppointmentScreen;

2)
    TBServiceBookings(fBookingObject).SetupNewAppointmentScreen;

3)
    (fBookingObject as TBServiceBookings).SetupNewAppointmentScreen;

我错过了什么?为什么每次都调用派生方法,即使我专门调用基本方法?

我剩下的唯一选择是创建一个基本类型的新变量,然后继续。但我已经有一个表单变量,这是我的对象,我只想调用一个特定的基类方法。

欢迎任何帮助!

2 个答案:

答案 0 :(得分:3)

除了你的问题背后的问题“你在哪里需要这个不寻常和有些可疑的构造?”,有一些可能性来访问祖先的虚拟方法。

  1. 非常难看:更改组件的类型:

    var
      SaveType: TClass;
    begin
      SaveType := Self.ClassType;
      PClass(Self)^ := TAncestor;
      try
        Self.AncestorMethod;
      finally
        PClass(Self)^ := SaveType
      end;
    end;
    
  2. 转换方法而不是类:

    type
      TInstanceMethod = procedure(Instance: TObject);
    
    begin
      TInstanceMethod(@TAncestor.AncestorMethod)(Self);
    end;
    
  3. 雇用一名班助手:

    type
      TAncestorHelper = class helper for TAncestor
        procedure AncestorMethodViaHelper;
      end;
    
    procedure TAncestorHelper.AncestorMethodViaHelper;
    begin
      inherited AncestorMethod;
    end;
    
    begin
      Self.AncestorMethodViaHelper;
    end;
    
  4. 在需要时,我自己总是使用第二种解决方案。但这只是在处理祖先时我无法改变,例如VCL。在你自己的框架内,你永远不需要这些黑客,因为你可以重新设计。

答案 1 :(得分:1)

如果班级是你的,你可以完全控制,所以不要覆盖你想要调用的基本方法。喜欢:

lm.fit

似乎是最简单的方法。还记得你可以简单地从overriden方法中调用Inherited方法。因此,如果您想要获得创意,可以传递一个布尔值,指示您是否需要基本功能。喜欢:

fBaseObject.ThisMethodBase; { calls the original }
fDerivedObject.ThisMethod;  { calls the new one }

面向对象编程很有趣。