??? 缺省構(gòu)造函數(shù)的問(wèn)題:base類(lèi)是父類(lèi),derived類(lèi)是子類(lèi),首先要說(shuō)明的是由于先有父類(lèi)后有子類(lèi),所以生成子類(lèi)之前要首先有父類(lèi)。class是由class的構(gòu)造函數(shù)constructor產(chǎn)生的,每一個(gè)class都有構(gòu)造函數(shù),如果你在編寫(xiě)自己的class時(shí)沒(méi)有編寫(xiě)任何構(gòu)造函數(shù),那么編譯器為你自動(dòng)產(chǎn)生一個(gè)缺省default構(gòu)造函數(shù)。這個(gè)default構(gòu)造函數(shù)實(shí)質(zhì)是空的,其中不包含任何代碼。但是一牽扯到繼承,它的問(wèn)題就出現(xiàn)了。
??? 如果父類(lèi)base class只有缺省構(gòu)造函數(shù),也就是編譯器自動(dòng)為你產(chǎn)生的。而子類(lèi)中也只有缺省構(gòu)造函數(shù),那么不會(huì)產(chǎn)生任何問(wèn)題,因?yàn)楫?dāng)你試圖產(chǎn)生一個(gè)子類(lèi)的實(shí)例時(shí),首先要執(zhí)行子類(lèi)的構(gòu)造函數(shù),但是由于子類(lèi)繼承父類(lèi),所以子類(lèi)的缺省構(gòu)造函數(shù)自動(dòng)調(diào)用父類(lèi)的缺省構(gòu)造函數(shù)。先產(chǎn)生父類(lèi)的實(shí)例,然后再產(chǎn)生子類(lèi)的實(shí)例。如下:
class base{
}
class derived extends base{
public static void main(String[] args){
??? derived d=new derived();
}
}
下面我自己顯式地加上了缺省構(gòu)造函數(shù):
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();
}
}
執(zhí)行結(jié)果如下:說(shuō)明了先產(chǎn)生base class然后是derived class。
base constructor
derived constructor
我要說(shuō)明的問(wèn)題出在如果base class有多個(gè)constructor而derived class也有多個(gè)constructor,這時(shí)子類(lèi)中的構(gòu)造函數(shù)缺省調(diào)用那個(gè)父類(lèi)的構(gòu)造函數(shù)呢?答案是調(diào)用父類(lèi)的缺省構(gòu)造函數(shù)。但是不是編譯器自動(dòng)為你生成的那個(gè)缺省構(gòu)造函數(shù)而是你自己顯式地寫(xiě)出來(lái)的缺省構(gòu)造函數(shù)。
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 類(lèi)的構(gòu)造函數(shù)注釋掉,則出錯(cuò)。
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
說(shuō)明子類(lèi)中的構(gòu)造函數(shù)找不到顯式寫(xiě)出的父類(lèi)中的缺省構(gòu)造函數(shù),所以出錯(cuò)。
那么如果你不想子類(lèi)的構(gòu)造函數(shù)調(diào)用你顯式寫(xiě)出的父類(lèi)中的缺省構(gòu)造函數(shù)怎么辦呢?如下例:
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)表示父類(lèi)的構(gòu)造函數(shù)base(i)請(qǐng)大家注意:一個(gè)是super(i)一個(gè)是super(8)。大家想想是為什么??
結(jié)論:
子類(lèi)如果有多個(gè)構(gòu)造函數(shù)的時(shí)候,父類(lèi)要么沒(méi)有構(gòu)造函數(shù),讓編譯器自動(dòng)產(chǎn)生,那么在執(zhí)行子類(lèi)構(gòu)造函數(shù)之前先執(zhí)行編譯器自動(dòng)產(chǎn)生的父類(lèi)的缺省構(gòu)造函數(shù);要么至少要有一個(gè)顯式的缺省構(gòu)造函數(shù)可以讓子類(lèi)的構(gòu)造函數(shù)調(diào)用。