“方法”%s'隐藏基类型'%s'的虚拟方法“。真正隐藏在哪里? [英] "Method '%s' hides virtual method of base type '%s'". What's really being hidden?

查看:147
本文介绍了“方法”%s'隐藏基类型'%s'的虚拟方法“。真正隐藏在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读 Ian Boyd 的构造函数系列问题( 1 2 3 4 ),我意识到我不会

After having read Ian Boyd's constructor series questions (1, 2, 3, 4), I realize I don't quite grasp the literal meaning on what's being hidden.

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

I know (correct me if I'm wrong) override's sole purpose is to be able to have polymorphic behavior, so that run-time can resolve a method depending on the actual type of an instance - as opposed to the declared type. Consider the following code:

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

Base.Proc1
Child.Proc1

Base.Proc2

警告在 TChild.Proc2 表示这种方法将隐藏对基地名相同方法的访问。我看到的是,如果我不覆盖 Proc2 ,我放弃了方法解析其实际类型的能力,而不是其基本类型。如何隐藏访问基础的方法?

The warning on TChild.Proc2 states that this method "will hide access to the base's method of the same name". What I see is, if I don't override Proc2 I loose the ability of the method's resolving to its actual type, not of its base type. How's that hiding access to base's method?

此外,关于警告的文档,作为警告的解决方案,它表示:

Further, down the documentation on the warning as a solution to the warning, it is stated that:


首先,您可以指定覆盖
,使派生类'程序也
虚拟,从而允许继承
调用仍然引用原来的
程序。

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呢,这个引用是什么呢?

Now, if I create a 'TChild' instance from a 'TChild' (no polymorphism), the inherited call in the non-overridden method clearly refers to the original procedure. If I create the 'Child' instance from a 'TBase', the call does not even resolve to a 'TChild' method, how could I call 'Inherited' that would refer to anything at all?

我有什么误会?

推荐答案

除此之外,您将无法定义

Amongs other thing, you won't be able to define

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

来自后代的TChild.Proc2 隐藏 TBase.Proc2。

because Proc2 that TGrandChild sees is the one from TChild that is not virtual. The TChild.Proc2 hide TBase.Proc2 from descendants.

编辑:

在回答Sertac的评论时:

In answer to Sertac's comment:

var 
  Base: TBase; 
  Child : TChild
begin 
  Child := TChild.Create;
  Base := Child;
  Base.Proc2; 
  Child.Proc2;

  Base.Free; 
  Readln; 

将输出

Base.Proc2
Base.Proc2
Child.Proc2

所以,什么似乎是对同一方法的调用两次实际上是调用2种不同的方法。这使得代码更难理解(这不是实际的)并产生意想不到的行为。

So, what seems to be a call to the same method twice is actually a call to 2 different methods. That makes code harder to understand (which is not practical) and yield unexpected behavior.

这篇关于“方法”%s'隐藏基类型'%s'的虚拟方法“。真正隐藏在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆