假设我们有这样的代码:
interface I
{
int P { get; }
}
class A : I
{
public virtual int P { get { return 0; } }
}
class B : A
{
public override int P { get { return 1; } }
}
class C : B, I
{
public int P { get { return 2; } }
}
A c = new C();
I ic = new C();
现在的问题是什么是c.P和ic.P?其实我知道会是 1 和 2,但你能解释一下为什么吗?
最佳答案
在 A c = new C();
的情况下,它将调用它发现的第一个正确覆盖 A
中声明的函数的函数。由于 C.P
没有覆盖它,而是隐藏了它,因此虚拟树遍历(多态解析)不会调用 C.P
函数,而是调用最低的一个在继承树中,即 B.P
。
在 I ic = new C();
的情况下,它会愉快地调用 P
的直接接口(interface)实现,因为它不关心多态虚拟调用,所以在这种情况下它调用 C.P
。
注意:这里的关键是 C
在其继承声明中直接包含 I
(即看起来像 class C : B, I
而不是class C : B
) 用于此行为。如果没有,ic.P
调用将再次引用覆盖继承的 P
,就像 c.P
一样,并且还会返回 1。
您应该会看到一条警告,上面写着以下内容,这有助于您了解某些地方做得不对:
'
C.P
' hides inherited member 'B.P
'. To make the current member override that implementation, add theoverride
keyword. Otherwise add thenew
keyword.
关于C# 复杂继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16637790/