1、背景 我:雖然通過繼承減少了代碼冗餘,但是,每一個子類的構造函數還是需要給所有屬性賦值的,很麻煩的。 師:這個好辦,用base就行啦。 我:貝司?還吉他呢! 師:別急,首先我們先介紹下實例化子類對象的時候調用父類構造函數。 運行結果: 從上面代碼分析可知: (1)執行 ChildClass ch ...
1、背景
我:雖然通過繼承減少了代碼冗餘,但是,每一個子類的構造函數還是需要給所有屬性賦值的,很麻煩的。
師:這個好辦,用base就行啦。
我:貝司?還吉他呢!
師:別急,首先我們先介紹下實例化子類對象的時候調用父類構造函數。
運行結果:
從上面代碼分析可知:
(1)執行 ChildClass child=new ChildClass(); 會首先調用父類無參構造函數(這個構造函數一定是無參構造函數),然後再調用子類無參構造函數,所以會先顯示
(2)然後再執行child.SayHello(); 因為子類是繼承父類的,所以直接調用父類的SayHello()方法,所以顯示
總結一下:
在實例化子類對象的時候,總是要調用父類的構造函數,並且總是調用無參構造函數。如果父類沒有無參構造函數,那麼子類的構造函數就會報錯
也就說說,子類是非常認死理的。必須去調用父類無參構造函數。這也是編程中容易出錯的地方。父類沒有編寫無參構造函數,導致子類無法編譯。
這時候解決錯誤有兩種方法:
(1)直接手動編寫父類無參構造函數
(2)在子類構造函數中使用base調用父類中的其他構造函數。Base後面括弧中的實際參數需要與被調用的父類構造函數參數保持一致。
2、Base的用法
base其實最大的使用地方在面相對象開發的多態性上,base可以完成創建派生類實例時調用其基類構造函數或者調用基類上已被其他方法重寫的方法。
Base有兩個用途
(1)在派生類中調用基類構造函數
(2)在派生類中調用基類的方法
2.1關於base調用基類構造函數
public class A { public A() { Console.WriteLine("Build A"); } } public class B:A { public B():base() { Console.WriteLine("Build B"); } static void Main() { B b = new B(); Console.ReadLine(); } }
輸出:
base調用基類有參構造和無參構造都可以的哦。
class B:A { public B():base() { Console.WriteLine("Build B"); } public B(string name) : base() { Console.WriteLine(name + "Build B(有參構造)"); } /* public B(string name) : base(name) { Console.WriteLine(name + "Build B(有參構造)"); } //*/ public override void Hello() { base.Hello();//調用基類的方法 Console.WriteLine("Hello,我是 B"); } } class A { public A() { Console.WriteLine("Build A"); } public A(string name) { Console.WriteLine(name+"Build A(有參構造)"); } public virtual void Hello() { Console.WriteLine("Hello,我是A"); } }
static void Main(string[] args) { B b = new B("祥子"); Console.ReadLine(); }
運行結果:
2.2關於base在派生類中調用基類的方法。
public class A { public virtual void Hello() { Console.WriteLine("Hello"); } } public class B : A { public override void Hello() { base.Hello();//調用基類的方法,顯示Hello Console.WriteLine("World"); } }
這樣如果程式調用B.Hello()獲得的效果將會使Hello World.