作为一个主要的java开发人员,有一天我意外地使用了new关键字而不是override,结果让我有点吃惊。
新关键字似乎删除了继承树中该级别方法的“虚拟性”,因此对降级到父类的子类实例调用方法不会解析为子类中的方法实现。
这种行为的实际用例是什么?
澄清:我理解当父母不是虚拟的时候使用new。我更好奇的是为什么编译器允许新的和虚拟的结合。
下面的示例说明了区别:

using System;

public class FooBar
{
    public virtual void AAA()
    {
        Console.WriteLine("FooBar:AAA");
    }

    public virtual void CCC()
    {
        Console.WriteLine("FooBar:CCC");
    }
}

public class Bar : FooBar
{
    public new void AAA()
    {
        Console.WriteLine("Bar:AAA");
    }

    public override void CCC()
    {
        Console.WriteLine("Bar:CCC");
    }
}

public class TestClass
{
    public static void Main()
    {
        FooBar a = new Bar();
        Bar b = new Bar();
        Console.WriteLine("Calling FooBar:AAA");
        a.AAA();
        Console.WriteLine("Calling FooBar:CCC");
        a.CCC();
        Console.WriteLine("Calling Bar:AAA");
        b.AAA();
        Console.WriteLine("Calling Bar:CCC");
        b.CCC();
        Console.ReadLine();
    }
}

这将产生以下输出:
Calling FooBar:AAA
FooBar:AAA
Calling FooBar:CCC
Bar:CCC
Calling Bar:AAA
Bar:AAA
Calling Bar:CCC
Bar:CCC

最佳答案

用例:
现在,您使用第三方库并从类Banana派生类Fruit
Peel中实现一个名为Banana的方法。Peel中没有Fruit
明天,第三方将发布一个新版本的库,其中包括一个virtualFruit.Peel方法
你明天重新编译代码。是否要覆盖Fruit.Peel?很可能不是-它可能有一个完全不同的含义。取而代之的是,用Banana.Peel隐藏它,所有现有代码都像今天一样工作。
换句话说,这主要是为了避免版本控制问题。在Java中,即使不想覆盖Fruit.peel,也可能导致难以诊断的错误。

08-07 18:10