建立衍生類別物件時,其內部包含一個基底類別的「子物件」,如同直接依基底類別建立物件般。此子物件必須正確初始化,唯一保證方式是在建構子中呼叫基底類別建構子。Java 會自動在衍生類別建構子插入基底類別建構子呼叫。
//: Cartoon.java
class Art { Art() { System.out.println("Art constructor"); } }
class Drawing extends Art { Drawing() { System.out.println("Drawing constructor"); } }
public class Cartoon extends Drawing {
Cartoon() { System.out.println("Cartoon constructor"); }
public static void main(String[] args) { Cartoon x = new Cartoon(); }
} ///:~
輸出順序:Art constructor → Drawing constructor → Cartoon constructor
證明建構由基底向外層層進行,基底類別在衍生類別存取前已就緒。即使未撰寫 Cartoon(),編譯器也會合成預設建構子並呼叫 super()。
//: Chess.java
class Game { Game(int i) { System.out.println("Game constructor"); } }
class BoardGame extends Game { BoardGame(int i) { super(i); System.out.println("BoardGame constructor"); } }
public class Chess extends BoardGame {
Chess() { super(11); System.out.println("Chess constructor"); }
public static void main(String[] args) { Chess x = new Chess(); }
} ///:~
若 BoardGame 未呼叫 super(i),編譯器將報錯找不到無參數 Game()。衍生類別建構子中,呼叫基底建構子必須是第一行敘述。
因建構子首行必須是 super(),衍生類別建構子無法捕捉基底類別建構子拋出的例外(第 9 章詳細探討)。