【发布时间】:2012-05-28 14:30:27
【问题描述】:
在阅读了这个 article 和那个 article 之后 - 我很困惑。
上面写着:
如果层次结构的不同级别有两种方法,则 将首先选择“更深”的,即使它不是“更好的功能” 成员”用于通话。
还有——
事实证明,如果你覆盖一个子类的基类方法 类,这不算声明它。
现在让我们回到我的问题:
案例一
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
}
public class Child : Base
{
public void Foo(object x) { "3".Dump();}
public override void Foo(int x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(10); //emits 3
}
好的。根据文章
将首先选择“更深”的一个,即使它不是“更好的功能。而且它不计算覆盖......
所以它是正确的,程序发出“3”。 (Foo(object x) 被执行)
让我们换行1行的顺序:
案例 2
public class Base
{
public virtual void Foo(int x) { "1".Dump();}
public void Foo(object x) { "3".Dump();} //<line being moved here
}
public class Child : Base
{
public override void Foo(int x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(10); //emits 2 !!!!
}
现在它发出“2”。
现在让我们将所有 int 更改为 object 并将所有 object 更改为 int :
案例 3
public class Base
{
public virtual void Foo(object x) { "1".Dump();}
public void Foo(int x) { "3".Dump();}
}
public class Child : Base
{
public override void Foo(object x) { "2".Dump();}
}
void Main()
{
Child c = new Child();
c.Foo(1); //emits "3"
}
问题:
问题#1: 在案例 2 中,Child 从其父亲那里继承了 Foo(object x) 并且他还覆盖了一个方法。
但是我们刚才不是这么说的吗:
事实证明,如果你覆盖一个子类的基类方法 类,这不算声明它
???
其实我们也没有声明继承函数……那么什么是规则在这种情况下呢?
问题#2: 在案例 3 中,Child 从其父亲那里继承了 Foo(int x) 并且他还覆盖了一个方法。
但是现在,他选择了它的父函数....
似乎override 只有在完全匹配的情况下才能获胜。
再次,规则是什么在这种情况下?
【问题讨论】:
-
我希望这只是出于好奇。 IMO,如果您的代码行为依赖于语言规范的令人困惑的极端情况,那么它的设计很糟糕。
-
@TimS。当然....好奇心让我更好地理解....
-
重载解析选择方法槽,然后重载被认为到达最派生的适用子类。情况 2 中选择了虚拟基方法(Child 的覆盖不算作声明);然后,由于它被覆盖,因此实际上调用了 Child 中的版本。