C#中的虚拟继承
Virtual Inheritance in C#
当我有一个方法阻止派生 class 覆盖基 class 中定义的虚拟方法时,我对虚拟继承的规则很困惑。这里有一些代码可以更好地解释我的问题:
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() 将在 class C?
上调用 DoWork() 的实现
Class D
现在有两个方法叫做 DoWork
.
第一个(方法 #1)是在 class A
中定义并在 class C
中重写的虚拟方法。 D
从 C
.
继承了这个方法
第二个(方法#2)是在 class D
本身中定义的非虚拟方法。此方法与方法#1 完全不同。
现在,您无法从类型为 D
的变量访问方法 #1,因为方法 #2 hides 方法 #1.
但是,您仍然可以使用 A
、B
或 C
.
类型的变量来访问方法 #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
当我有一个方法阻止派生 class 覆盖基 class 中定义的虚拟方法时,我对虚拟继承的规则很困惑。这里有一些代码可以更好地解释我的问题:
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() 将在 class C?
上调用 DoWork() 的实现Class D
现在有两个方法叫做 DoWork
.
第一个(方法 #1)是在 class A
中定义并在 class C
中重写的虚拟方法。 D
从 C
.
第二个(方法#2)是在 class D
本身中定义的非虚拟方法。此方法与方法#1 完全不同。
现在,您无法从类型为 D
的变量访问方法 #1,因为方法 #2 hides 方法 #1.
但是,您仍然可以使用 A
、B
或 C
.
为了更清楚地说明这一点,这里有一个例子:
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