如果代码中没有显式调用(继承;),Delphi 是否调用重写过程中的继承,我有以下结构(从超类到子类)

TForm >> TBaseForm >> TAnyOtherForm

项目中的所有表单都将从 TBaseForm 派生,因为它将具有用于每个表单的所有标准设置和破坏性部分(安全性、验证等)。

TBaseForm 有 onCreate 和 onDestroy 过程以及执行此操作的代码,但是如果有人(即我)忘记添加继承到 TAnyOtherForm 上的 onCreate,Delphi 会为我调用它吗?我在网上找到了一些参考资料,说它不是必需的,但没有地方说如果从代码中省略它,是否会调用它。

另外,如果它确实为我调用继承,那么它什么时候会调用它?

有帮助吗?

解决方案

不,如果您将调用保留为继承,则不会调用它。否则,将不可能重写方法并完全忽略它的父版本。

其他提示

值得一提的是,任何对象的Destroy中不调用inherited都会导致内存泄漏。有一些工具可以在源代码中检查这一点。

必须显式地进行继承的调用。一般来说,没有语言会在等效情况下自动调用继承的函数(不包括类构造函数)。

很容易忘记在类构造函数中进行继承调用。在这种情况下,如果基类需要初始化任何数据,则可能会发生访问冲突。

也许您可以重写 TBaseForm 类中的 DoCreate 和 DoDestory,这样您就可以确保无论子类的实现如何,都会执行某些代码。

// interface

TBaseForm = Class(TForm)
...
Protected
    Procedure DoCreate(Sender : TObject); Override;
End

// implementation

Procedure TBaseForm.DoCreate(Sender : TObject);
Begin
    // do work here

    // let parent call the OnCreate property  
    Inherited DoCreate(Sender);
End;

Inherited 必须在后代对象以及视觉形式继承中显式调用。如果您使用类完成,那么如果您将定义标记为覆盖(但不用于重新引入),它会自动添加继承。如果您使用可视表单继承,那么当您通过表单编辑器添加新的事件处理程序时,它也会添加继承。

正如其他人指出的那样,继承的代码不会被隐式调用。您必须显式调用它。这为您提供了一些有用的灵活性。例如,您可能希望在继承的代码之前执行一些预处理代码,然后再执行一些后处理代码。这可能看起来像:

procedure TMyCalcObject.SolveForX;
begin
  ResetCalcState;
  inherited SolveForX;
  PostProcessSolveForX;
end;

不。这就是覆盖的全部意义。

您必须显式调用它。这提供了很大的灵活性,因为您可以选择在代码中的哪个点调用继承的方法。但这也是错误的一大来源。很容易忘记调用继承的函数,并且编译器无法判断您是故意这样做还是只是忘记了。

应该有某种指令“skip_inherited”告诉编译器您不想调用继承的方法。

如果编译器没有找到“inherited”或“skip_inherited”,那么它很容易报告错误。那意味着你忘记了。但不幸的是,CodeGear 中没有人想到这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top