在阅读完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.
输出结果为:
Base.Proc1
Child.Proc1
Base.Proc2
关于TChild.Proc2
的警告说明了该方法“将隐藏对基类同名方法的访问”。但是我看到的是,如果我没有覆盖Proc2
,我就失去了将方法解析为其实际类型而不是其基类型的能力。那么这是如何隐藏基类方法的访问呢?
此外,在解决警告的文档中,它指出:
首先,您可以指定override来使派生类的过程也是虚拟的,从而允许继承的调用仍然引用原始过程。
现在,如果我从'TChild'创建一个'TChild'实例(无多态性),非重载方法中的继承调用显然会引用原始过程。如果我从'TBase'创建'Child'实例,则调用甚至不解析为'TChild'方法,我怎么调用'Inherited'以引用任何东西呢?
我有什么误解吗?