這是我的讀書筆記,希望能夠對大家學習java有所協助。 所有代碼都經過測試,測試環境: java version "1.4.0-rc" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91) Java HotSpot(TM) Client VM (build 1.4.0-rc-b91, mixed mode) 如大家發現任何錯誤,或有任何意見請不吝賜教。 預設建構函式的問題:base類是父類,derived類是子類,首先要 說明的是由於先有父類後有子類,所以產生子類之前要首先有父類。 class是由class的建構函式constructor產生的,每一個class都有 建構函式,如果你在編寫自己的class時沒有編寫任何建構函式,那麼 編譯器為你自動產生一個預設default建構函式。這個default建構函式 實質是空的,其中不包含任何代碼。但是一牽扯到繼承,它的問題就出現 了。 如果父類base class只有預設建構函式,也就是編譯器自動為你產生的。 而子類中也只有預設建構函式,那麼不會產生任何問題,因為當你試圖產生 一個子類的執行個體時,首先要執行子類的建構函式,但是由於子類繼承父類, 所以子類的預設建構函式自動調用父類的預設建構函式。先產生父類的執行個體, 然後再產生子類的執行個體。如下: class base{ } class derived extends base{ public static void main(String[] args){ derived d=new derived(); } } 下面我自己顯式地加上了預設建構函式: class base{ base(){ System.out.println("base constructor"); } } class derived extends base{ derived(){ System.out.println("derived constructor"); } public static void main(String[] args){ derived d=new derived(); } } 執行結果如下:說明了先產生base class然後是derived class。 base constructor derived constructor 我要說明的問題出在如果base class有多個constructor 而derived class也有多個constructor,這時子類中的建構函式預設 調用那個父類的建構函式呢?答案是調用父類的預設建構函式。 但是不是編譯器自動為你產生的那個預設建構函式而是你自己顯式地 寫出來的預設建構函式。 class base{ base(){ System.out.println("base constructor"); } base(int i){ System.out.println("base constructor int i"); } } class derived extends base{ derived(){ System.out.println("derived constructor"); } derived(int i){ System.out.println("derived constructor int i"); } public static void main(String[] args){ derived d=new derived(); derived t=new derived(9); } } D:/java/thinking/think6>java derived base constructor derived constructor base constructor derived constructor int i 如果將base 類的建構函式注釋掉,則出錯。 class base{ // base(){ // System.out.println("base constructor"); // } base(int i){ System.out.println("base constructor int i"); } } class derived extends base{ derived(){ System.out.println("derived constructor"); } derived(int i){ System.out.println("derived constructor int i"); } public static void main(String[] args){ derived d=new derived(); derived t=new derived(9); } } D:/java/thinking/think6>javac derived.java derived.java:10: cannot resolve symbol symbol : constructor base () location: class base derived(){ ^ derived.java:13: cannot resolve symbol symbol : constructor base () location: class base derived(int i){ ^ 2 errors 說明子類中的建構函式找不到顯式寫出的父類中的預設 建構函式,所以出錯。 那麼如果你不想子類的建構函式調用你顯式寫出的父類中的預設 建構函式怎麼辦呢? 如下例: class base{ // base(){ // System.out.println("base constructor"); // } base(int i){ System.out.println("base constructor int i"); } } class derived extends base{ derived(){ super(8); System.out.println("derived constructor"); } derived(int i){ super(i); System.out.println("derived constructor int i"); } public static void main(String[] args){ derived d=new derived(); derived t=new derived(9); } } D:/java/thinking/think6>java derived base constructor int i derived constructor base constructor int i derived constructor int i super(i)表示父類的建構函式base(i)請大家注意 一個是super(i)一個是super(8)。 大家想想是為什嗎?? 結論:子類如果有多個建構函式的時候,父類要麼沒有建構函式, 讓編譯器自動產生,那麼在執行子類建構函式之前先執行編 譯器自動產生的父類的預設建構函式;要麼至少要有一個顯 式的預設建構函式可以讓子類的建構函式調用。 |