C# 中的 override 和 new 关键字有啥区别?
Posted
技术标签:
【中文标题】C# 中的 override 和 new 关键字有啥区别?【英文标题】:What is the difference between the override and new keywords in C#?C# 中的 override 和 new 关键字有什么区别? 【发布时间】:2011-09-28 09:44:18 【问题描述】:在类层次结构中定义方法时,C# 中的override
和new
关键字有什么区别?
【问题讨论】:
【参考方案1】:以下页面很好地总结了您的问题。
Knowing When to Use Override and New Keywords
总结
重写:当基类的方法在派生类中被重写时,将使用派生类中的版本,即使调用代码不“知道”该对象是派生类的一个实例。
新建:如果使用new关键字代替override,派生类中的方法不会覆盖基类中的方法,它只是隐藏它。
如果您没有指定 new 或 overrides,则结果输出与您指定 new 时相同,但您也会收到编译器警告(因为您可能不知道您在基类方法,或者实际上您可能想要覆盖它,只是忘记包含关键字)。
覆盖:与基类中的虚拟/抽象/覆盖类型的方法一起使用
新增:当基类没有将方法声明为虚拟/抽象/覆盖时
【讨论】:
您能否在此处也包含重要信息。它有助于将信息保留在这里并防止链接失效(不太可能与 MSDN 博客,但你永远不知道)。 大声笑“不太可能”我收到重定向,然后是“拒绝访问您没有查看/下载此项目的权限。”【参考方案2】:new
将使用全新的方法(可能具有或不具有相同的签名)覆盖该方法,而不是覆盖它(在这种情况下,新方法必须具有相同的签名),这意味着多态不会工作。例如,您有这些类:
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
,编译器不会“查找”继承的方法。但是,对于 virtual
和 override
,它可以工作。
我强烈建议您避免使用new
;充其量是令人困惑的,因为您定义的方法的名称可能会被识别为其他东西,而在最坏的情况下,它可以隐藏错误,引入看似不可能的错误,并使扩展功能变得困难。
【讨论】:
这应该是公认的答案。它实际上通过示例解释了差异和含义。接受的答案非常模糊。 在使用接口时会发生类似的情况(如 B 扩展 A,A 用Hello()
实现接口,将 B 分配给具有接口类型的变量)。最好在您的回答中澄清这一点,因为这就是我正在寻找的情况。【参考方案3】:
看起来像一个老问题,让我尝试一个不同的答案:
new
:顾名思义,它是继承层次结构家族中的一个新成员,它将用作更下游的基础成员(如果标记为虚拟)。
override
:这意味着我不接受我的父类的成员实现,我会做不同的事情。
【讨论】:
【参考方案4】:考虑以下类层次结构:
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
【讨论】:
很好的例子,我认为如果你将Program
类和其他类分成两个单独的代码块,输出与方法调用内联作为注释,例如base2.Foo(); // Base => Foo
。我也会省略命名空间和导入,但如果你想提供可运行的代码,那么只需链接到 dotnetfiddle.net【参考方案5】:
override
允许您覆盖基类中的虚拟方法,以便您可以放入不同的实现。new
将隐藏基类中的非虚拟方法。
【讨论】:
我知道的就这么多了,但是 override 将有效地隐藏基类方法 没有覆盖不会隐藏基类方法。 Override 将对基类方法的调用转换为对派生类方法的调用。在某种程度上,派生类中的方法与基类中的方法相同。而对于new
,它是一个完全独立的方法,只是恰好具有相同的名称。
@CodeInChaos 感谢您说出我想说的比我能说的更好:)【参考方案6】:
简单的区别在于override
表示该方法是虚拟的(它与基类中的virtual
关键字进行传导),而new
仅表示它不是虚拟的,它是一个常规覆盖。
所以两者都是真正的函数覆盖,一个是具有虚拟特性的,另一个不是。
具体是什么意思?它只是意味着多态性不会在“新”方法中发挥作用。
下面的图片说明可能会清楚地说明这一点。
注意如果你不使用new
关键字,它仍然是隐含的,但它会产生一个警告信息。
【讨论】:
以上是关于C# 中的 override 和 new 关键字有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
c#基础-19.重写(override)和覆盖(new)的区别