首先先看override和new的语法特征:
-
override
1. override是派生类用来重写基类中方法的;
2. override不能重写非虚方法和静态方法;
3. override只能重写用virtual、abstract、override修饰的方法;
4. 不能使用修饰符 new、static、virtual 或 abstract 来修改 override 方法。
new
1. new是派生类用来隐藏基类中的方法的;也就是说在派生类中“看不到”基类中的方法;
2. 如果要在派生类中隐藏(不是重写)基类中的方法,而没有使用new关键字,编译时会出现一个警告,提示如果是要隐藏基类中的方法,请使用new关键字【默认是new修饰的】;
3. 派生类可以隐藏基类中的虚方法,也可以隐藏基类中的普通方法。
4. 如果在派生类中用private来修饰new 方法,那么只在该派生类中隐藏了基类中的方法,在该派生类之外,相当于没有隐藏基类中的方法;
5. 如果在派生类中隐藏了基类中的方法,在该派生类的派生类中,将延续对该派生类对基类方法的隐藏。
测试结论:
- 经测试:只有类中有虚方法重写override,才会表现出运行时类型方法特征。其他无论是不是虚方法,是不是有new 修饰,是不是有override 修饰,都表现出编译时类型方法特征【即声明的类型是什么就调用什么方法】。
以下是测试方法内容:
//1、虚方法重写override,运行时类型方法特征。
//1.1、虚方法未重写,编译时【未重写派生类调用基类方法】产生装箱或转型
//1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】
//2、非虚方法重写。编译时【重写派生类隐藏基类方法】
//3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】产生装箱或转型
代码
1 public class TestShape 2 { 3 public static void Main(string[] args) 4 { 5 //主要测试:1、虚方法重写override,运行时类型方法特征。 6 //1.1、虚方法未重写,编译时【未重写派生类调用基类方法】装箱或转型 7 //1.2、虚方法重写new或没有new也没有override,编译时【重写派生类隐藏基类方法】 8 //2、非虚方法重写。编译时【重写派生类隐藏基类方法】 9 //3、非虚方法未重写,调用基类方法。编译时【未重写派生类调用基类方法】装箱或转型 10 11 //1、 12 Shape shape = new Circle(); 13 shape.MethodVirtual();//circle override MethodVirtual 14 //2、编译时 15 Diamond diamond = new Diamond(); 16 diamond.Method();//Diamond default Method 17 Shape s = new Diamond(); 18 s.Method();//base Method call 19 //结论:非虚方法重写编译时 类型方法。 20 //1.2 编译时 21 diamond.MethodVirtual();//Diamond default MethodVirtual,没有使用override默认是new 22 s.MethodVirtual();//base MethodVirtual call,没有使用override默认是new 23 //3、编译时 24 Circle circle = new Circle(); 25 circle.Method();//base Method call 26 } 27 } 28 public class Shape 29 { 30 public virtual void MethodVirtual() 31 { 32 Console.WriteLine("base MethodVirtual call"); 33 } 34 public void Method() 35 { 36 Console.WriteLine("base Method call"); 37 } 38 } 39 public class Circle: Shape 40 { 41 public override void MethodVirtual() 42 { 43 Console.WriteLine("circle override MethodVirtual"); 44 } 45 } 46 public class Triangle : Shape 47 { 48 public new void MethodVirtual() 49 { 50 Console.WriteLine("Triangle new MethodVirtual"); 51 } 52 public new void Method() 53 { 54 Console.WriteLine("Triangle new Method"); 55 } 56 } 57 public class Diamond : Shape 58 { 59 //默认是使用了new关键字 60 public void MethodVirtual() 61 { 62 Console.WriteLine("Diamond default MethodVirtual"); 63 } 64 public void Method() 65 { 66 Console.WriteLine("Diamond default Method"); 67 } 68 }
语言对比:
Java——默认虚方法
默认情况下,Java中的方法都是虚方法。假如希望方法具有非虚的行为,就必须显式密封它。相反,C#的方法默认为非虚方法。