6

这是一个显示虚拟方法的小代码。

class A
{
  public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
  public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
  new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
  public override void F() { Console.WriteLine("D.F"); }
}

class Test
{
  static void Main() 
  {
    D d = new D();
    A a = d;
    B b = d;        

    a.F();
    b.F();        
 }
}

此代码正在打印以下输出:

B.F
B.F

我不明白为什么 aF() 会打印 BF ?

我认为它会打印 DF,因为 B 类覆盖了 A 类的 F(),然后使用“new”关键字将这个方法隐藏在 C 类中,然后在 D 类中再次被覆盖。所以最后 DF 留下了。

但它没有这样做。你能解释一下为什么要打印BF吗?

4

4 回答 4

5
A a = d;
a.F();

它会发现F()如下。

  1. 首先进入class A
  2. 然后在class B
  3. 然后在class C
  4. 然后在class D

现在 F()将在A和中找到B。因此B.F()将被调用。在class CF() 中是不同的(因为它是新实现并且不会从 A/B 覆盖)。所以在第 3 步中,将找不到 cF()。在 D 类中,它覆盖了 C 创建的新函数,因此它也不会被找到。

由于 new 关键字,生成的代码如下(关于虚拟覆盖)

    class A
    {
        public virtual void F() { Console.WriteLine("A.F"); }
    }
    class B: A
    {
        public override void F() { Console.WriteLine("B.F"); }
    }
    class C: B
    {
        public virtual void F1() { Console.WriteLine("C.F"); }
    }
    class D: C
    {
        public override void F1() { Console.WriteLine("D.F"); }
    }
于 2012-07-06T05:36:06.137 回答
2

与允许多态性的方法覆盖不同,使用new关键字隐藏方法只是命名问题(请注意,使用new只是删除了您正在隐藏某些内容的警告)。

在 classC中,当您声明:

new public virtual void F() { ... }

在这里,您定义了一个与超类无关的全新方法F(),它恰好具有相同的名称。

当 的 实例F被分配给类型为Aor的变量时B,使用这些变量调用F()将指向超类定义的方法。

想象一下,如果您没有调用C' 方法F(),而是调用不同的方法,例如G(). 以下代码无法编译:

a.G();
b.G();

由于变量静态类型为Aor B,编译器看不到新声明的方法。在您的示例中情况相同,只是超类恰好有名为F()要调用的原始方法。

于 2012-07-06T05:33:24.843 回答
1

AF 被 BF 覆盖 因此,当调用 AF 时,它会执行 BF BF is 'connected' to 'AF'。

现在 CF 用 new 关键字隐藏 BF。CF 未连接到 BF/AF 当您创建 C 并调用 F() 时,它将执行 CF 如果将 C 转换为类型 A 或 B,并调用 F,它将执行 BF,因为 BF 和 AF 是连接的。

CF 被 DF 覆盖。它们是连接的。当CF或DF被调用时,它将执行DF 现在当你将对象D转换为A或B,并调用F()时,它将调用BF

希望这有助于使其更清晰。

于 2012-07-06T05:35:39.460 回答
0

正如其他人已经指出的那样,C 中的 new 关键字隐藏了 F 的重载,因此在 C 或 D 中找不到合适的 F 重载。

如果您需要有关 C# 找到正确重载的更多详细信息,请阅读这两篇:

Jon Skeet:深入了解 C#,重载一章

Visual Studio 2010:重大变化,此处:重载解决方案

于 2012-07-06T05:53:24.303 回答