【问题标题】:Virtual Inheritance in C# [duplicate]C#中的虚拟继承[重复]
【发布时间】:2015-12-06 18:08:23
【问题描述】:

当我有一个防止派生类覆盖基类中定义的虚拟方法的方法时,我与虚拟继承的规则非常混淆。这里有一些代码可以更好地解释我的问题:

using System;

namespace ConsoleApplication1
{
    public class A
    {
        public virtual void DoWork()
        {
            Console.WriteLine("A.DoWork()");
        }
    }
    public class B : A
    {
        public override void DoWork()
        {
            Console.WriteLine("B.DoWork()");
        }
    }

    public class C : B
    {
        public sealed override void DoWork()
        {
            Console.WriteLine("C.DoWork()");
        }
    }

    public class D : C
    {
        public new void DoWork()
        {
            Console.WriteLine("D.DoWork()");
        }
    }

    public class MyMainClass
    {
        public static void Main()
        {
            B b = new D();
            b.DoWork();

            C c = new D();
            c.DoWork();

            A a = new D();
            a.DoWork();

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }
}

输出

C.DoWork()
C.DoWork()
C.DoWork()
按任意键退出

确实,如果使用 B 类型的变量来访问 C 的实例为B b = new C(); b.DoWork() 将导致调用 C 的 DoWork() 实现,因为 C 覆盖了 A 的虚拟 DoWork()。

但是为什么当使用C、B或A类型的变量来访问D的实例时是这样的

B b = new D();
C c = new D();
A a = new D();

对它们中的每一个调用 DoWork() 都会调用 C 类上的 DoWork() 实现?

【问题讨论】:

标签: c# polymorphism overriding sealed


【解决方案1】:

D 类现在有两个称为 DoWork 的方法。

第一个(方法#1)是在类A 中定义并在类C 中覆盖的虚方法。 DC 继承此方法。

第二个(方法#2)是在类D 本身中定义的非虚拟方法。此方法与方法#1 完全不同。

现在,您无法从 D 类型的变量访问方法 #1,因为方法 #2 hides 方法 #1。

但是,您仍然可以使用ABC 类型的变量来访问方法#1。

为了更清楚,这里有一个例子:

D var_d = new D();

B var_b = var_d;

var_d.DoWork(); //This accesses method #2 on an object of type D

var_b.DoWork(); //This accesses method #1 on the same object

【讨论】:

  • 嘿!多谢!一些澄清顺便说一句... 1) var_b 是 B 类型的变量,具有 D 类型的值,只能访问 C 类的重写方法(方法#1),而不是 B 类和 C 类的重写方法(只是思考因为 D 是 C 的子类,它是 B 的子类,所以它不继承 B 和 C 的重写方法吗?) 2)另外,为什么 var_b 只对方法 #1 而不是方法 #2 感兴趣/跨度>
  • 1) 你不是说B和A吗?这些是相同的方法(方法#1)。但是由于该方法是虚拟的,所以 C 已经通过覆盖它来更改该方法的实现。
  • 2) var_b 对方法 #2 一无所知。它只知道方法#1。这是真的,因为方法#2 是在类D 上定义的。请注意,虽然方法 #1 已在类 D 中被覆盖,但它的 定义 在类 A 中。这就是var_b 知道方法#1 的原因。
猜你喜欢
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 2016-03-26
相关资源
最近更新 更多