阅读Ian Boyd的构造函数系列问题(1,2,3,4)后,我意识到我不太了解隐藏内容的字面意思。
我知道(如果我错了,请纠正我)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/