TearSnow Fan


[C#] new修饰符和override修饰符的区别

我们都知道new关键字可以作为运算符来创建对象,但其另一个常用的用法是作为修饰符来隐藏基类中被继承的成员。

根据MSDN的解释:

在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然不使用 new 修饰符也可以隐藏成员,但会生成警告。 如果使用 new 显式隐藏成员,则会取消此警告,并记录要替换为派生版本这一事实。当然,在不会隐藏继承成员的声明中使用 new 修饰符也将会生成警告。

从作用上来看,似乎new修饰符和override修饰符有些类似。首先需要明确的是,对同一成员同时使用 new 和 override 是错误的做法,因为这两个修饰符的含义互斥。 new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏的(可以通过添加base关键字实现访问);而override 修饰符会扩展该继承成员的实现。

请看下面的例子:

using System;
class Parent
{
public void F() { Console.WriteLine("Parent.F"); }
public virtual void G() { Console.WriteLine("Parent.G"); }
}
class Child: Parent
{
new public void F() { Console.WriteLine("Child.F"); }
public override void G() { Console.WriteLine("Child.G"); }
}
class Test
{
static void Main()
{
Child b = new Child();
Parent a = b;
a.F();
b.F();
a.G();
b.G();
}
}

程序经编译后执行输出:

Parent.F
Child.F
Child.G
Child.G

我们可以看到class Child中F()方法的声明采取了重写(new)的办法来屏蔽class Parent中的非虚方法F()的声明。而G()方法就采用了覆盖(override)的办法来提供方法的多态机制。需要注意的是重写(new)方法和覆盖(override)方法的不同,从本质上讲重写方法是编译时绑定,而覆盖方法是运行时绑定。值得指出的是虚方法不可以是静态方法——也就是说不可以用static和virtual同时修饰一个方法,这由它的运行时类型辨析机制所决定。override必须和virtual配合使用,当然也不能和static同时使用。

如果你用override,则无论调用的是A类还是B类中的TEST(),系统都会找到它实质类的TEST();
如果是用的New,则可以通过类型转换调用到基类的TEST();下面是override的情况:

A a = new A();
B b = new B();
A a1=new B();
a.Test();//调用A中Test();
b.Test();//调用B中Test();
a1.Test();//调用B中Test();系统会自动识别a1是B的实例
((A)b).Test();//与上面相同下面是new的情况:
A a = new A();
B b = new B();
A a1=new B();
a.Test();//调用A中Test();
b.Test();//调用B中Test();
a1.Test();//调用A中Test();
((A)b).Test();//与上面相同

下面总结一下C#中new关键字的作用,考虑以下几个问题:

1、new一个class对象和new一个struct或者new一个enum有什么不同?

答:new一个class时,new完成2个内容:一是调用newobj命令为实例在托管堆中分配内存,二是调用构造函数实现对象初始化。

new一个struct时,new运算符用于调用其构造函数,完成实例的初始化。

2、new在.NET中除了创建对象实例外,还可以做什么?

答:new关键字:作为运算符可以创建对象和调用构造函数;

作为修饰符可以用于隐藏基类中被继承的成员,实现派生类中隐藏基类的virtual方法,不能和override共存;

作为约束可以在泛型声明中约束可能用作类型参数的参数类型,即new约束指定泛型类声明中的任何类型参数都必须要有公共的无参构造函数;

使用new关键字实现多态。

3、new运算符可以重载吗?

答:new运算符不可以重载。

4、泛型中new关键字的作用?

答:new运算符用于返回一个引用,指向系统分配的托管堆的内存地址,new分配内存失败,将引发OutOfMemoryException异常。

5、new一个继承下来的方法和override有什么区别?

答:new是隐藏基类方法,override是覆写基类方法。如果要访问new隐藏了的基类成员需要使用base关键字实现。

6、int i和int i = new int()有什么不同?

答:new一个int时,new运算符用于初始化其值为0,使构造函数完成更优越的初始化操作。

参考资料:

[1] C#语法的问题:new 修饰符 和 override 修饰符有什么区别?

[2] 谈谈new关键字 by PualMa

[3] MSDN资料:new修饰符(C#参考)

本文固定链接: http://blog.xieyc.com/differences-between-modifier-new-and-override/ | 小谢的小站

该日志由 xieyc 于2013年07月01日发表在 编程 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: [C#] new修饰符和override修饰符的区别 | 小谢的小站
关键字:

目前共有 2 条留言 【 访客:2 条, 博主:0 条 】 访客以 2:0 暂时领先博主!

  1. 沙发
    微历史:

    很不错的C#基础,初学者必看

    2013-07-01 09:59

发表评论

:wink: :neutral: :mad: :twisted: :smile: :shock: :sad: :roll: :oops: :eek: :mrgreen: :lol: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

快捷键:Ctrl+Enter