假设我们有这样的代码:
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,但你能解释一下为什么吗?
发布于 2013-05-20 02:13:19
在A c = new C();的情况下,它将调用它发现的第一个函数,该函数正确地覆盖了A中声明的函数。因为C.P没有覆盖它,而是隐藏了它,所以虚拟树遍历(多态解析)不会调用C.P函数,而是调用继承树中最低的函数,即B.P。
对于I ic = new C();,它将愉快地调用P的直接接口实现,因为它不关心多态虚拟调用,所以在这种情况下它调用C.P。
注意:这里的关键是C在其继承声明中直接使用了I (即看起来像class C : B, I而不是class C : B)。如果没有,ic.P调用将再次引用被覆盖的继承P,就像c.P一样,并且也将返回1。
您应该会看到一个警告,上面写着以下内容,这有助于给您提供一些线索,说明有些事情做得不是很正确:
'
C.P‘隐藏继承的成员'B.P’。若要使当前成员重写该实现,请添加override关键字。否则,添加new关键字。
发布于 2013-05-20 02:12:16
class B : A意味着类B继承了类A,简而言之,意味着类B将拥有类A所具有的所有属性-函数。但是当你说覆盖时,(“关键字”是public override int P )意味着对于'P‘,B类将以不同的方式运行。这就像“隐藏”A类中的“P”。
Inheritance
发布于 2013-05-20 02:13:52
This Page与你的帖子非常相关。在这种情况下,发生的情况取决于被视为当前类型的类型。因此,对于c,P是1,因为它使用的是A中的P方法,该方法已被B覆盖。它调用的是子链最下端的方法,该方法仍然是A的方法。对于ic,将再次为子链最下游的位置调用该方法,这次是在C处,因为它是I中存在的方法的有效实现。这在第一种情况下不会发生,因为C.P不会覆盖A.P。
https://stackoverflow.com/questions/16637790
复制相似问题