總結一下使用類繼承和多態時,實例化順序以及方法繼承重寫中new,virtual、abstract、override的用法和規則:ide
繼承關係:實例化對象時,做用類型範圍在最初基類到具體實例對象的類之間(中間包括父類子類,成員訪問權限:private、protected、public):函數
一、 子類構造器必須指定擁有父類訪問權限的構造器:base(xxx),默認無參構造器;spa
二、 先實例化基類,再實例化子類,再子類的子類....最後到要實例的類(構造函數執行順序先父後子...);code
三、 在運行方法時,就運行當前所屬類型中的方法:對象
1).當遇到繼承新建new方法時,說明子類方法爲新方法與父類不具重寫關係,仍然運行當前所屬類型中的方法;blog
2).當遇到虛virtual、抽象abstract、繼承覆蓋override方法時,說明方法具體實現已重寫,就運行離具體對象類型關係最近的一個類的重寫方法。固然關係最近的是自身。繼承
最後例子說明一下:string
這裏提一下:抽象類沒法直接實例化即不能顯式調用構造器(new,反射),須要藉助子類實例化時,構造函數調用抽象類的構造函數如:base()進行實例化,就是爲繼承和重寫而生的;抽象實例成員只能放在抽象類中;靜態類只能有靜態成員(包括構造函數),不能顯式調用構造器,初始加載時系統經過構造函數自動建立一個靜態對象。it
1 public abstract class A 2 { 3 public int x; 4 public A() 5 { 6 x = -1; 7 Console.WriteLine("x={0}", x); 8 Print1(); 9 Print2(); 10 } 11 public virtual void Print1() 12 { 13 x = 1; 14 Console.WriteLine("x={0}", x); 15 } 16 17 public virtual void Print2() 18 { 19 x = 2; 20 Console.WriteLine("x={0}", x); 21 } 22 } 23 24 public class B : A 25 { 26 public int y; 27 public B() 28 { 29 y = -1; 30 Console.WriteLine("x={0},y={1}", x, y); 31 Print1(); 32 Print2(); 33 } 34 35 public override void Print1() 36 { 37 x = 3; 38 y = 1; 39 Console.WriteLine("x={0},y={1}", x, y); 40 } 41 //該方法將繼承的從新建立,自身及其後子類重寫均爲這個方法 42 public new virtual void Print2() 43 { 44 x = 4; 45 y = 2; 46 Console.WriteLine("x={0},y={1}", x, y); 47 } 48 } 49 public class C : B 50 { 51 //該方法將繼承的從新建立,自身及其後子類繼承的均爲這個方法 52 public new void Print1() 53 { 54 x = 5; 55 y = 3; 56 Console.WriteLine("x={0},y={1}", x, y); 57 } 58 //該方法重寫自父類B,而不是基類A 59 public override void Print2() 60 { 61 x = 4; 62 y = 2; 63 Console.WriteLine("x={0},y={1}", x, y); 64 } 65 } 66 public static class D 67 { 68 public static string _name; 69 static D() 70 { 71 _name = "小明"; 72 } 73 }
主程序:class
1 static void Main(string[] args) 2 { 3 A c = new C(); 4 c.Print1(); 5 c.Print2(); 6 //靜態、抽象類反射不能建立 7 //Type type = typeof(A); 8 //var constructor = type.GetConstructor(Type.EmptyTypes); 9 //Object obj = constructor.Invoke(null); 10 //Console.WriteLine(obj.GetType().Name); 11 //Type type = typeof(D); 12 //var constructor = type.GetConstructor(BindingFlags.Static|BindingFlags.NonPublic,null,Type.EmptyTypes,null); 13 //Object obj = constructor.Invoke(null); 14 //Console.WriteLine(obj.GetType().Name); 15 Console.WriteLine(D._name); 16 Console.ReadKey(); 17 } 18
輸出結果: