C#中的覆盖和新关键字有什么区别?

时间:2011-07-04 21:27:20

标签: c# .net oop

在类层次结构中定义方法时,C#中的overridenew关键字有什么区别?

6 个答案:

答案 0 :(得分:82)

以下页面很好地总结了您的问题。

Knowing When to Use Override and New Keywords

<强>摘要

覆盖:在派生类中重写基类的方法时,使用派生类中的版本,即使调用代码没有“知道”该对象是派生类的一个实例。

:如果使用new关键字而不是override,派生类中的方法不会覆盖基类中的方法,它只会隐藏它。

如果未指定new或覆盖,则结果输出与指定new相同,但您也会收到编译器警告(因为您可能不知道您正在隐藏方法基类方法,或者你可能想要覆盖它,只是忘了包含关键字)。

覆盖:与基类中的virtual / abstract / override类型的方法一起使用

:当基类未将方法声明为virtual / abstract / override

答案 1 :(得分:64)

new将使用一个全新的方法(可能具有或不具有相同的签名)来遮蔽该方法,而不是覆盖它(在这种情况下,新方法必须具有相同的签名),这意味着多态性赢得了& #39;工作。例如,您有这些类:

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}

如果你这样做:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3

由于您可以使用new定义新的方法签名,因此编译器无法知道A的实例实际上是B的实例并且是新的方法B定义应该可用。当父对象的方法,属性,字段或事件未使用new声明时,可以使用virtual,并且由于缺少virtual,编译器赢了&#39}。 t“查找”继承的方法。但是,对于virtualoverride,它可以正常工作。

我强烈建议你避免new;充其量,这是令人困惑的,因为你正在定义一个名称可以被识别为其他东西的方法,最糟糕的是,它可以隐藏错误,引入看似不可能的错误,并使扩展功能变得困难。

答案 2 :(得分:8)

看起来像一个老问题,让我尝试不同的答案:

  1. new:正如名称所示,它是继承层次结构系列中的新成员,它将用作进一步向下链的基本成员(如果标记为虚拟)。

  2. override:这意味着我不接受我父类的成员实施,我将采取不同的做法。

答案 3 :(得分:2)

考虑以下类层次结构:

using System;

namespace ConsoleApp
{     
     public static class Program
     {   
          public static void Main(string[] args)
          {    
               Overrider overrider = new Overrider();
               Base base1 = overrider;
               overrider.Foo();
               base1.Foo();

               Hider hider = new Hider();
               Base base2 = hider;
               hider.Foo();
               base2.Foo();
          }   
     }   

     public class Base
     {
         public virtual void Foo()
         {
             Console.WriteLine("Base      => Foo");
         }
     }

     public class Overrider : Base
     {
         public override void Foo()
         {
             Console.WriteLine("Overrider => Foo");
         }
     }

     public class Hider : Base
     {
         public new void Foo()
         {
             Console.WriteLine("Hider     => Foo");
         }
     }
}    

上述代码的输出必须是:

Overrider => Foo
Overrider => Foo

Hider     => Foo
Base      => Foo
  
      
  • 子类overrides是一个虚拟方法,应用override modifier
  •   
  • 如果您想故意hide成员,在这种情况下,您可以将new modifier应用于子类中的成员。 The new modifier does nothing more than suppress the compiler warning that would otherwise result
  •   

答案 4 :(得分:1)

override允许您覆盖基类中的虚方法,以便您可以放入不同的实现。new将隐藏基类中的非虚方法。

答案 5 :(得分:0)

简单的区别是 override 表示该方法是虚拟的(它与基类中的 virtual 关键字进行传导)而 new 仅表示它不是虚拟的,它是一个常规覆盖.

所以两者都是函数覆盖,一个是虚拟特性,另一个没有。

具体是什么意思?这只是意味着“新”方法不会使用多态性。

下图可能会说明这一点。

enter image description here

请注意,如果您不使用 new 关键字,它仍然是隐含的,但会生成警告消息。