上期介紹了繼承與多態基礎概念,本期深入探討七大進階細節。
子類構造器必須調用父類構造器。若無顯式 super(...),自動調用父類無參構造器。若父類無無參構造器,子類必須顯式調用帶參構造器,否則編譯錯誤。
public class Base {
private String member;
public Base(String member) { this.member = member; } // 唯一構造器
}
public class Child extends Base {
public Child(String member) { super(member); } // 必須顯式調用
}
父類構造器調用可重寫方法時,會觸發多態調用子類方法,但此時子類字段尚未初始化(默認值)。
public class Base {
public Base() { test(); } // 調用可重寫方法
public void test() {}
}
public class Child extends Base {
private int a = 123;
@Override public void test() { System.out.println(a); }
}
// main: new Child() → 輸出 0(而非 123),再調用 c.test() → 123
最佳實踐:構造器中只調用 private/final/static 方法。
實例變量、靜態變量、靜態方法、private 方法採用靜態綁定(編譯期根據引用類型決定),非 private 實例方法採用動態綁定(運行期根據對象類型決定)。
Base b = new Child(); Child c = new Child(); b.s → Base.s (靜態綁定) c.s → Child.s b.staticTest() → Base c.staticTest() → Child b.m → Base.m c.m → Child.m
方法調用解析優先級:先按參數類型匹配度選擇重載版本,再看動態類型進行動態綁定。完全匹配優於兼容匹配;子類同等匹配度下優先。
Base b = new Child()(自動,安全)Child c = (Child) b(需強轉,運行時檢查)安全判斷:b instanceof Child。只有動態類型為 Child 或其子類時才能轉換成功。
模板方法模式典型應用:父類定義算法骨架(public),關鍵步驟交給 protected 方法由子類實現。
public class Base {
protected int currentStep;
protected void step1() {} protected void step2() {}
public void action() { currentStep=1; step1(); currentStep=2; step2(); }
}
public class Child extends Base {
@Override protected void step1() { println("step " + currentStep); }
@Override protected void step2() { println("step " + currentStep); }
}
子類重寫方法不能降低父類可見性:
public → 子必須 publicprotected → 子可 protected 或 public原因:繼承體現 is-a,子類必須支援父類所有對外行為。
final class:不可被繼承final method:不可被重寫final variable:不可重新賦值下期將探討:子類對象創建完整過程、動態綁定底層實現原理。關注「老馬說編程」獲取最新文章。
