C# 复杂继承

标签 c# inheritance

假设我们有这样的代码:

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 the override keyword. Otherwise add the new keyword.

关于C# 复杂继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16637790/

相关文章:

c++ - 从构造函数调用虚函数

c# - 使用 C# 编辑二进制文件中的文本

c# - 如何忽略生成的 JSON 中的空对象文字?

c# - 最大发送尝试次数

c++ - 在初始化时使用基类的 const

objective-c - 调用父类(super class)中的可选方法 (Objective-C)

c# - 使现有的 Windows 窗体可继承

c# - FileHelpers Csv 阅读器 - 无法转换 dd-mmm-yyyy 日期时间格式

c# - 如何在 asp.net mvc 中以编程方式确定路由前缀?

c++ - 虚拟基类函数中派生类的大小