我有一个基础对象类型: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;
我错过了什么?为什么每次都调用派生方法,即使我专门调用基本方法?
我剩下的唯一选择是创建一个基本类型的新变量,然后继续。但我已经有一个表单变量,这是我的对象,我只想调用一个特定的基类方法。
欢迎任何帮助!
答案 0 :(得分:3)
除了你的问题背后的问题“你在哪里需要这个不寻常和有些可疑的构造?”,有一些可能性来访问祖先的虚拟方法。
非常难看:更改组件的类型:
var
SaveType: TClass;
begin
SaveType := Self.ClassType;
PClass(Self)^ := TAncestor;
try
Self.AncestorMethod;
finally
PClass(Self)^ := SaveType
end;
end;
转换方法而不是类:
type
TInstanceMethod = procedure(Instance: TObject);
begin
TInstanceMethod(@TAncestor.AncestorMethod)(Self);
end;
雇用一名班助手:
type
TAncestorHelper = class helper for TAncestor
procedure AncestorMethodViaHelper;
end;
procedure TAncestorHelper.AncestorMethodViaHelper;
begin
inherited AncestorMethod;
end;
begin
Self.AncestorMethodViaHelper;
end;
在需要时,我自己总是使用第二种解决方案。但这只是在处理祖先时我无法改变,例如VCL。在你自己的框架内,你永远不需要这些黑客,因为你可以重新设计。
答案 1 :(得分:1)
如果班级是你的,你可以完全控制,所以不要覆盖你想要调用的基本方法。喜欢:
lm.fit
似乎是最简单的方法。还记得你可以简单地从overriden方法中调用Inherited方法。因此,如果您想要获得创意,可以传递一个布尔值,指示您是否需要基本功能。喜欢:
fBaseObject.ThisMethodBase; { calls the original }
fDerivedObject.ThisMethod; { calls the new one }
面向对象编程很有趣。