阅读Ian Boyd的构造函数系列问题(1234)后,我意识到我不太了解隐藏内容的字面意思。

我知道(如果我错了,请纠正我)override的唯一目的是能够具有多态行为,以便运行时可以根据实例的实际类型(而不是声明的类型)解析方法。考虑以下代码:

type
  TBase = class
    procedure Proc1; virtual;
    procedure Proc2; virtual;
  end;

  TChild = class(TBase)
    procedure Proc1; override;
    procedure Proc2;            // <- [DCC Warning]
  end;

procedure TBase.Proc1;
begin
  Writeln('Base.Proc1');
end;
procedure TBase.Proc2;
begin
  Writeln('Base.Proc2');
end;

procedure TChild.Proc1;
begin
  inherited Proc1;
  Writeln('Child.Proc1');
end;
procedure TChild.Proc2;
begin
  inherited Proc2;
  Writeln('Child.Proc2');
end;

var
  Base: TBase;
begin
  Base := TChild.Create;
  Base.Proc1;
  Writeln;
  Base.Proc2;
  Base.Free;
  Readln;
end.

哪个输出:



TChild.Proc2 states that上的警告此方法“将隐藏对同名基类方法的访问”。我看到的是,如果我不重写Proc2,则会失去方法解析为实际类型而不是其基本类型的能力。隐藏访问base方法的方式如何?

此外,在警告文档中作为警告的一种解决方案,它指出:



现在,如果我从“TChild”(没有多态性)创建“TChild”实例,则非重写方法中的继承调用显然会引用原始过程。如果我从“TBase”创建“Child”实例,则该调用甚至无法解析为“TChild”方法,我如何才能调用将完全引用任何内容的“Inherited”?

我有什么误会?

最佳答案

除其他事项外,您将无法定义

TGrandChild = class(TChild)
  procedure Proc2; override;
end;

因为TGrandChild看到的Proc2是来自TChild的非虚拟的Proc2。 TChild.Proc2对子孙隐藏TBase.Proc2。

编辑:

在回答Sertac的评论时:
var
  Base: TBase;
  Child : TChild
begin
  Child := TChild.Create;
  Base := Child;
  Base.Proc2;
  Child.Proc2;

  Base.Free;
  Readln;

那将输出
Base.Proc2
Base.Proc2
Child.Proc2

因此,似乎两次调用同一方法实际上是对两个不同方法的调用。这使代码更难于理解(这是不切实际的),并产生意外行为。

关于delphi - “Method '%s ' hides virtual method of base type '%s '”。真正隐藏的是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3878576/

10-11 23:17