??? 缺省構造函數的問題: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)。大家想想是為什么??
結論:
子類如果有多個構造函數的時候,父類要么沒有構造函數,讓編譯器自動產生,那么在執行子類構造函數之前先執行編譯器自動產生的父類的缺省構造函數;要么至少要有一個顯式的缺省構造函數可以讓子類的構造函數調用。
posted on 2009-08-09 13:18
jadmin 閱讀(111)
評論(0) 編輯 收藏