-
28-09-2019 - |
题
这是两个简单的类,最初都没有关键字(虚拟,超载,覆盖,重新引入):
TComputer = class(TObject)
public
constructor Create(Teapot: Integer);
end;
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer; Handle: string);
end;
我将在上面的定义中表示这些较短:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
并在构造时 TCellPhone
只有一个构造函数(int
, string
) - 因为祖先构造函数已被隐藏。我将指出可见的构造函数 TCellPhone
作为:
- 茶壶:整数;句柄:字符串
现在,对于这个问题,前三个案例很有意义,第四案没有:
1.祖先的构造者被后代隐藏:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
Teapot: Integer; Handle: string
这是有道理的,祖先的构造函数被隐藏了,因为我已经宣布了一个新的构造函数。
2.祖先虚拟构造函数被后代隐藏:
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
Teapot: Integer; Handle: string
这是有道理的,祖先的构造函数被隐藏了,因为我已经宣布了一个新的构造函数。
笔记: 因为祖先是虚拟的:Delphi会警告您您隐藏了虚拟祖先(在上一个隐藏静态构造函数的例子中:没人在乎,所以没有警告)。警告可以被抑制(意思是“是的,是的,我隐藏了一个虚拟构造函数。 意思是 这样做。”)通过添加 重新引入:
TComputer = class(TObject) constructor Create(Teapot: Integer); virtual; TCellPhone = class(TComputer) constructor Create(Teapot: Integer; Handle: string); reintroduce;
3.祖先的构造者由于超载而没有隐藏在后代中:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
Teapot: Integer; Handle: string
Teapot: Integer
这是有道理的,因为后代构造函数是 超载 祖先的,因此两者都可以存在。祖先的构造函数并没有被隐藏。
4.虚拟祖先构造者不隐藏在后代,因为超载 - 但仍然有警告:
这种情况是没有道理的:
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
Teapot: Integer; Handle: string
Teapot: Integer
方法“创建”隐藏基本类型的虚拟方法'tcomputer'
这没什么意义。不仅祖先 不是 隐藏,后代被超载;它甚至不应该 是 抱怨。
是什么赋予了?
解决方案
Delphi的文档说:
如果您超载虚拟方法,请在后代类重新列出时使用重新引入指令。例如,
type T1 = class(TObject) procedure Test(I: Integer); overload; virtual; end; T2 = class(T1) procedure Test(S: string); reintroduce; overload; end;
没有重新引入的指令,它仍然可以正如您注意到的那样起作用,但是您会收到警告。
另外,您实际上是在隐藏tobject。创建,但这与警告无关。如果您认为您可能希望访问Tobject。也要创建,请执行此操作:
type
TComputer = class(TObject)
constructor Create(Teapot: Integer); reintroduce; overload; virtual;
end;
type
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
end;
其他提示
我会同意特立尼达。警告背后的逻辑可能仅考虑祖先方法是虚拟/动态,以及后代方法是否被标记为覆盖或重新引入。
这也适用于“正常”方法。
可以通过放置来抑制它 reintroduce
之前 overload
修改器或通过将覆盖的构造函添加到后代类中,该类别仅委派给祖先构造函数。
我已经注意到了。据我所知,警告是一个错误,因为继承的方法没有隐藏。如果还没有,应在QC.Embarcadero.com上报告。