程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 講解Java構造函數的繼承問題

講解Java構造函數的繼承問題

編輯:關於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)。

大家想想是為什麼??

結論:子類如果有多個構造函數的時候,父類要麼沒有構造函數, 讓編譯器自動產生,那麼在執行子類構造函數之前先執行編 譯器自動產生的父類的缺省構造函數;要麼至少要有一個顯式的缺省構造函數可以讓子類的構造函數調用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved