C# override与new关键字对比
在 C# 中,new 关键字可用作运算符、修饰符或约束。
- new 运算符:用于创建对象和调用构造函数。
- 例如:object obj = new object();
- new 修饰符:用于向基类成员隐藏继承成员(既然是隐藏,那么还是可以被“发现”的)。
- new 约束:用于在泛型声明中约束可能用作类型参数的参数的类型(即如果需要在泛型类型内部实例化参数类型的对象,那么必须对类型参数加以默认构造函数约束)。
- 例如:
-
class Factory<U> where U: new() { public static U GetNew(){ return new U(); } } class Program { static void Main() { int i=Factory<int>.GetNew(); object obj=Factory<object>.GetNew(); //此时 i的值等于int类型的默认 值0;obj对象引用一个object类型的实例 } }
下面本文就C#中new关键字作为修饰符的情况下与override关键字进行比较。
1、new关键字作为修饰符时,可以“隐藏”基类的方法,也就是说该方法是派生类新定义的,不是基类的方法(可以隐藏的方法包括virtual方法、实例方法,对于静态方法虽然不会提示语法错误,但好像没有实际意义,因为静态方法本身就是类本身的方法,但是不能对基类的抽象方法进行重写)。注意:程序运行时调用哪个方法取决于对象声明,如果声明为基类对象,那么实际调用的是基类的没有被隐藏的方法。如(MSDN):
// Define the base class class Car { public virtual void DescribeCar() { System.Console.WriteLine("Four wheels and an engine."); } } // Define the derived classes class ConvertibleCar : Car { public new virtual void DescribeCar() { base.DescribeCar(); System.Console.WriteLine("A roof that opens up."); } }
public static void TestCars1() { Car car1 = new Car(); car1.DescribeCar(); System.Console.WriteLine("----------"); ConvertibleCar car2 = new ConvertibleCar(); car2.DescribeCar(); System.Console.WriteLine("----------"); }
运行结果如下:
Four wheels and an engine.
----------
Four wheels and an engine.
A roof that opens up.
----------
---------------------------------------------------------------------
如果声明为基类类型,那么实际调用的方法为基类的同名方法,而非new的方法(即发现暂时隐藏基类方法)
public static void TestCars2() { Car[] cars = new Car[3]; cars[0] = new Car(); cars[1] = new ConvertibleCar(); } foreach (Car vehicle in cars) { System.Console.WriteLine("Car object: " + vehicle.GetType()); vehicle.DescribeCar(); System.Console.WriteLine("----------"); }
运行结果如下:
Car object: YourApplication.Car
Four wheels and an engine.
----------
Car object: YourApplication.ConvertibleCar
Four wheels and an engine.
----------
2、override修饰符作用即对基类方法(包括abstract方法、virtual方法、override方法)的覆盖,以实现C#语言中的多态。在C++语言中多态是通过虚函数表来实现的,即所谓的动态联编。C#中的动态联编使用虚拟方法或者抽象方法来实现。我们将类中的一些方法声明为虚拟或者抽象的,就意味着这些方法在子类中会有不同的实现,编译器为虚拟方法和抽象方法调用生成调用代码,这些代码在运行时能按照对象实例本身的类类型动态选择所定义的虚拟或者抽象方法。(注意:抽象方法其实是隐式的虚方法,这点可以通过类比C++中的虚函数和纯虚函数来理解。抽象方法与虚方法的区别仅在于抽象方法不能提供实现,由派生类使用override关键字进行实现;虚方法需要在基类提供实现,派生类可以不重新实现,可以重写-override,也可以隐藏-new。)
使用override关键字对基类的方法进行覆盖时有以下几项原则:
重写的基类方法必须和Override的方法具有相同的签名(方法返回值、方法名、参数),此关键字不可以用于重写非虚方法和静态方法,包括abstract方法、virtual方法、override方法;
override方法不可修改访问修饰符,即与基类的virtual、abstract、override方法具有相同的访问可见性;
(第一次写在园子里面写博客希望各位高手指点~~~)

浙公网安备 33010602011771号