【问题标题】:How to overload a Delphi class function如何重载 Delphi 类函数
【发布时间】:2014-07-14 18:42:28
【问题描述】:

我有一个像这样的 Delphi (2007) 类函数:

Class Function InitGlobal : TForm; Overload; Virtual; Abstract;

在一些后代类中我尝试:

Class Function InitGlobal : TDescendentForm; Overload; Override;

但 Delphi 抱怨 TDescendentForm.InitGlobal 与之前的声明不同(尽管存在“Overload”指令)。

我猜函数结果类型不能重载。如果有的话,定义这种重载的正确方法是什么?

我检查了 Function overloading by return type?,但它提到了进行这种重载的利弊,而没有提及 Delphi。

【问题讨论】:

  • 依我的拙见,你要么overload要么override,但你不能同时做这两个。 overload 需要有不同的方法签名,而override 表示该方法应替换派生类型中的同名方法。也许更详细的代码示例可以提供更多帮助。
  • 你的意见无关紧要,@Will。事实是你可以同时做这两件事。它在 RTL 和 VCL 中多次发生。
  • 感谢@RobKennedy 提供的信息。在我的职业生涯中,我从来没有同时做到这两点,因为我一直认为重载是只为给定行为定义不同参数的方法,而覆盖是只重新定义对象行为的方法。我从来没有碰巧同时做这两件事,而且我倾向于认为这是一个设计缺陷,不知何故。但是,嘿,如果您说它在 RTL 和 VCL 中多次完成,那么出于某种我根本不需要的原因,它一定是好的。 =)

标签: delphi methods overloading


【解决方案1】:

函数重载只能基于参数,不能基于返回值。您无法拥有两个仅在返回值上有所不同的重载。

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

您可以做的是覆盖该函数,并保持相同的签名。您可以删除 overload 指令。那么你的派生函数将如下所示:

class function InitGlobal: TForm; override;

现在,没有什么可以阻止您返回TDescendentForm 的实例。那仍然是TForm。您在这里要做的是在运行时返回一个派生类型。

实现可能如下所示:

Result := TDescendentForm.Create(...);
// compile time type of Result is TForm, but that is assignment compatible
// at run time with an instance of TDescendentForm

【讨论】:

  • 当然,他可以返回 TDescendentForm,但调用 InitGlobal 的代码不会知道这一点,也无法访问 TDescendentForm 上的项目,除非它强制转换为 TDescendentForm(例如,使用 as)。但是如果它无论如何都知道 TDescendentForm,那么就失去了多态性的优势,并且函数根本不必是虚拟的。
  • @Rudy 但是它可以在返回的实例上调用任何虚拟方法。您不一定需要在编译时知道类型才能利用派生类的行为。
  • 正如 David 所说,重载仅适用于参数签名,而不适用于返回值,因此使用不太优雅的解决方案,正如 Rudy 建议的那样:TDescendantForm(TDescendantForm.InitGlobal ()).SomeMethodInDescendant。如果接受重载结果类型,则可以删除第一个强制转换,从而使代码更清晰
  • 您需要更多帮助吗?
猜你喜欢
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多