C#中重写(override)、重载(overload)、隐藏(new)区别

一、重写(override)

override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。

重写(覆盖)的规则:

   1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.

   2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。

   3、重写的方法的返回值必须和被重写的方法的返回一致;

   4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;

   5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没s有对其进行重写。

   6、静态方法不能被重写为非静态的方法(会编译出错)。

 

 1 override就是子类将父类的方法重新实现了一遍。
 2 new就是说这个方法就是子类自己的,跟父类没有任何继承关系关系,仅仅是重名 
 3 
 4     public class A
 5     {
 6         public virtual string Function()
 7         {
 8             return "1";
 9         }
10     }
11     public class B : A
12     {
13         public override string Function()
14         {
15             return "2";
16         }
17     }
18     public class C : A
19     {
20         public new string Function()
21         {
22             return "3";
23         }
24     }
25 
26     public class JustForTest
27     {
28         public void DoTest()
29         {
30             B b = new B();
31             C c = new C();
32 
33             Console.WriteLine(b.Function());
34             Console.WriteLine(c.Function());
35             Console.WriteLine((b as A).Function());//这两个就体现出来了,B还是调用自己,返回2
36             Console.WriteLine((c as A).Function());//C调用的是基类,返回0
37         }
38     }
View Code

 

 

二、overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。

重载的规则:

   1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);

   2、不能通过访问权限、返回类型、抛出的异常进行重载;

   3、方法的异常类型和数目不会对重载造成影响;

多态的概念比较复杂,有多种意义的多态,一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。

一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。

举个例子:

 

 1 public class Shape
 2 
 3 {
 4 
 5    public static void main(String[] args){
 6 
 7      Triangle tri = new Triangle();
 8 
 9      System.out.println("Triangle is a type of shape? " + tri.isShape());// 继承
10 
11      Shape shape = new Triangle();
12 
13      System.out.println("My shape has " + shape.getSides() + " sides."); // 多态
14 
15      Rectangle Rec = new Rectangle();
16 
17      Shape shape2 = Rec;
18 
19      System.out.println("My shape has " + shape2.getSides(Rec) + " sides."); //重载
20 
21    }
22 
23    public boolean isShape(){
24 
25      return true;
26 
27    }
28 
29    public int getSides(){
30 
31      return 0 ;
32 
33    }
34 
35    public int getSides(Triangle tri){ //重载
36 
37      return 3 ;
38 
39    }
40 
41    public int getSides(Rectangle rec){ //重载
42 
43     return 4 ;
44 
45    }
46 
47 }
48 
49 class Triangle extends Shape
50 
51 {
52 
53    public int getSides() { //重写,实现多态
54 
55      return 3;
56 
57    }
58 
59 }
60 
61 class Rectangle extends Shape
62 
63 {
64 
65    public int getSides(int i) { //重载
66 
67     return i;
68 
69    }
70 
71 }
View Code

 

 

注意Triangle类的方法是重写,而Rectangle类的方法是重载。对两者比较,可以发现多态对重载的优点:

如果用重载,则在父类里要对应每一个子类都重载一个取得边数的方法;

如果用多态,则父类只提供取得边数的接口,至于取得哪个形状的边数,怎样取得,在子类里各自实现(重写)。

三、重写(override)与隐藏(new)的区别

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace TestClass
 8 {
 9     class Program
10     {
11         /*
12            重写和隐藏的定义:
13            重写:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.
14            隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。
15             
16            自己的理解:
17            比如父类A,有个方法标记为virtual,a(){}子类B继承A,也声明一个方法a(){}   
18            如果B里面的a()使用override,那么访问A的方法时实际上调用了B里面声明的方法,相当于A的方法被覆盖了,new就不是,
19            访问A的a还是A里面定义的方法,访问B就是B里面定义的方法.
20            说白了:new是覆盖,override是重写,“覆盖”并不意味着“删除”,但“重写”意味着“删除”,
21            这就是“覆盖”和“重写”的区别  
22            隐藏(new)示例:
23         */
24         static void Main(string[] args)
25         {
26             B b = new B();
27             b.ClassA();
28             A a = b;
29             a.ClassA();
30 
31             Console.WriteLine("\n");
32 
33             B2 b2 = new B2();
34             b2.ClassA2();
35             A2 a2 = b2;
36             a2.ClassA2();
37 
38             Console.WriteLine("\n");
39             A2 newa2 = new A2();
40             newa2.ClassA2();
41 
42             Console.ReadKey();
43         }
44     }
45 
46     //
47     class A
48     {
49         public void ClassA()
50         {
51             Console.WriteLine("A.ClassA()");
52         }
53     }
54     class B : A
55     {
56         new public void ClassA()
57         {
58             Console.WriteLine("B.ClassA()");
59         }
60 
61     }
62 
63     //
64     class A2
65     {
66         public virtual void ClassA2()
67         {
68             Console.WriteLine("A2.ClassA2()");
69         }
70     }
71     class B2 : A2
72     {
73         public override void ClassA2()
74         {
75             Console.WriteLine("B2.ClassA2()");
76         }
77     }
78 }
View Code

 

 

posted @ 2016-05-04 14:19  腾冲  阅读(925)  评论(0)    收藏  举报