在阅读了
Ian Boyd的构造函数系列问题(
1,2,3,4)后,我意识到我并没有完全掌握隐藏内容的字面含义.
我知道(纠正我,如果我错了)覆盖的唯一目的是能够具有多态行为,以便运行时可以根据实例的实际类型解析方法 – 而不是声明的类型.请考虑以下代码:
- 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.Proc1Base.Proc2
TChild.Proc2 states that上的警告此方法“将隐藏对同名基础方法的访问”.我所看到的是,如果我不重写Proc2,我会失去该方法解析其实际类型的能力,而不是其基本类型.如何隐藏对base方法的访问?
此外,关于警告的文档作为警告的解决方案,声明:
First,you could specify override to
make the derived class’ procedure also
virtual,and thus allowing inherited
calls to still reference the original
procedure.
现在,如果我从’TChild'(没有多态)创建’TChild’实例,则非重写方法中的继承调用显然是指原始过程.如果我从’TBase’创建’Child’实例,则调用甚至不会解析为’TChild’方法,我怎么能调用’Inherited’来引用任何东西呢?
我有什么误会?
解决方法
Amongs其他的东西,你将无法定义
- TGrandChild = class(TChild)
- procedure Proc2; override;
- end;
因为TGrandChild看到的Proc2是来自TChild的非虚拟的. 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