6

这是两个简单的类,最初都没有关键字(virtual、overload、override、reintroduce):

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

  • 茶壶:整数;句柄:字符串

现在对于这个问题,前 3 种情况是有道理的,第 4 种情况没有:

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 会警告你隐藏了虚拟祖先(在前面的隐藏静态构造函数的例子中:没人关心,所以没有警告)。可以通过添加reintroduce来抑制警告(意思是“是的,是的,我正在隐藏一个虚拟构造函数。我 打算这样做。”):

    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”的虚拟方法

这没什么意义。不仅祖先隐藏,后代超载;它甚至不应该抱怨。

是什么赋予了?

4

3 回答 3

5

德尔福的文档说:

如果重载虚方法,请在后代类中重新声明它时使用 reintroduce 指令。例如,

type
  T1 = class(TObject)
    procedure Test(I: Integer); overload; virtual;
  end;
  T2 = class(T1)
    procedure Test(S: string); reintroduce; overload;
  end;

如您所见,如果没有 reintroduce 指令,它仍然有效,但您会收到警告。

此外,您实际上隐藏了 TObject.Create,但它与警告无关。如果您认为您可能还想访问 TObject.Create,请执行以下操作:

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;
于 2010-10-08T20:03:38.383 回答
2

我同意特立尼达。警告背后的逻辑可能只关注祖先方法是否为虚拟/动态以及后代方法是否标记为覆盖或重新引入。

这也适用于“正常”方法。

可以通过将其放在修饰符reintroduce之前overload或通过将重写的构造函数添加到简单地委托给祖先构造函数的后代类来抑制它。

于 2010-10-08T19:39:42.483 回答
1

我已经注意到了。据我所知,警告是一个错误,因为继承的方法没有隐藏。如果还没有,应该在 qc.embarcadero.com 上报告。

于 2010-10-08T18:21:31.717 回答