如何重载Delphi类函数

如何重载Delphi类函数,delphi,methods,overloading,Delphi,Methods,Overloading,我有一个Delphi(2007)类函数,如下所示: Class Function InitGlobal : TForm; Overload; Virtual; Abstract; class function InitGlobal: TForm; override; Result := TDescendentForm.Create(...); // compile time type of Result is TForm, but that is assignment compatible

我有一个Delphi(2007)类函数,如下所示:

Class Function InitGlobal : TForm; Overload; Virtual; Abstract;
class function InitGlobal: TForm; override;
Result := TDescendentForm.Create(...);
// compile time type of Result is TForm, but that is assignment compatible
// at run time with an instance of TDescendentForm
在某些后代类中,我尝试:

Class Function InitGlobal : TDescendentForm; Overload; Override;
但是Delphi抱怨说
TDescendentForm.InitGlobal
与之前的声明不同(尽管存在“重载”指令)

我猜函数结果类型不能重载。哪种方法是定义此类重载(如果有)的正确方法


我选中了,但它提到了在不提及Delphi的情况下进行此类重载的利弊。

函数重载只能基于参数,而不能基于返回值。您不可能有两个只在返回值上不同的重载

此外,即使您可以这样做,您也在尝试使用
覆盖
,并更改函数的签名。这也是不可能的。重写必须具有与被重写函数相同的签名

您可以做的是重写该函数,并保留相同的签名。您可以删除
重载
指令。那么您的派生函数将如下所示:

Class Function InitGlobal : TForm; Overload; Virtual; Abstract;
class function InitGlobal: TForm; override;
Result := TDescendentForm.Create(...);
// compile time type of Result is TForm, but that is assignment compatible
// at run time with an instance of TDescendentForm
现在,没有什么可以阻止您返回
TDescendentForm
的实例。这仍然是一种形式。这里要做的是在运行时返回一个派生类型

实现可能如下所示:

Class Function InitGlobal : TForm; Overload; Virtual; Abstract;
class function InitGlobal: TForm; override;
Result := TDescendentForm.Create(...);
// compile time type of Result is TForm, but that is assignment compatible
// at run time with an instance of TDescendentForm

依我的拙见,你要么是
过载
,要么是
覆盖
,但你不能同时做这两件事。
重载
需要具有不同的方法签名,而
重写
表示该方法将替换派生类型中同名的方法。也许一个更详细的代码示例可以进一步帮助您。您的意见与此无关,@Will。事实上,你可以同时做这两件事。这在RTL和VCL中发生过好几次。谢谢你提供的信息,@RobKennedy。在我的职业生涯中,我从未同时做过这两件事,因为我一直期望重载是只为给定行为定义不同参数的方法,而重写是只重新定义对象行为的方法。我从来没有碰巧同时做过这两件事,不知怎么的,我倾向于认为这是一个设计缺陷。但是,嘿,如果你说它在RTL和VCL中执行了多次,那么它一定是好的,因为我根本不需要它当然,他可以返回TDescendentForm,但是调用InitGlobal的代码不会知道这一点,也无法访问TDescendentForm上的项目,除非它强制转换为TDescendentForm(例如,使用
as
)。但是,如果它知道TDescendentForm,多态性的优势就消失了,函数也不必是虚拟的。@Rudy,但它可以对返回的实例调用任何虚拟方法。您不必在编译时知道类型,就可以利用派生类的行为。正如David所说,重载只对参数签名有效,而不返回值,因此使用了不太优雅的解决方案,如Rudy所建议的:tdescendatform(tdescendatform.InitGlobal()).SomeMethodIndesdent。如果可以接受重载结果类型,则可以删除第一个强制转换,从而生成更清晰的代码。是否需要更多帮助?