繼承 = extends + 構造器鏈 + 方法復用 + 多態調用。本文通過 Pet (父類) → Dog (子類) 完整代碼,演示構造器調用順序、字段初始化、方法繼承調用、向上轉型賦值,助你從語法走向實戰。
public class Pet {
private String name = "無名氏";
private int health = 100;
private int love = 0;
// 無參構造器
public Pet() {
this.health = 95;
System.out.println("執行寵物的無參構造方法");
}
// 有參構造器
public Pet(String name) {
this.name = name;
}
// Getter
public String getName() { return name; }
public int getHealth() { return health; }
public int getLove() { return love; }
// 通用行為
public void print() {
System.out.println("寵物的自白:\n我的名字叫" + this.name
+ ",我的健康值是" + this.health
+ ",我和主人的親密程度是" + this.love + "。");
}
}
public class Dog extends Pet {
private String strain; // 品種,子類特有
// 有參構造器:必須顯式調用 super(name) 初始化父類字段
public Dog(String name, String strain) {
super(name); // ★ 關鍵:調用父類有參構造器
this.strain = strain;
}
public String getStrain() { return strain; }
// 繼承了 Pet 的 print()、getName()、getHealth()、getLove()
}
public class TestInheritance {
public static void main(String[] args) {
// 1. 創建父類對象
Pet pet = new Pet("貝貝");
pet.print();
// 輸出: 寵物的自白:我的名字叫貝貝,我的健康值是95,我和主人的親密程度是0。
System.out.println("-------------------");
// 2. 創建子類對象
Dog dog = new Dog("歐歐", "雪納瑞");
dog.print(); // ★ 直接調用父類方法!
// 輸出: 寵物的自白:我的名字叫歐歐,我的健康值是95,我和主人的親密程度是0。
// 3. 向上轉型:父類引用指向子類對象
Pet petRef = new Dog("大黃", "拉布拉多");
petRef.print(); // 動態綁定:調用 Dog 繼承的 print()
// petRef.getStrain(); // 編譯錯誤:父類引用不可訪問子類特有方法
}
}
new Dog("歐歐", "雪納瑞")
│
├─ Dog(String, String) 構造器
│ ├─ super("歐歐") → Pet(String) 構造器執行
│ │ ├─ this.name = "歐歐"
│ │ └─ 返回
│ └─ this.strain = "雪納瑞"
└─ Dog 對象創建完成
{ name="歐歐", health=95, love=0, strain="雪納瑞" }
┌─────────────────────────────────────┐
│ Dog Object (堆) │
├─────────────────────────────────────┤
│ Pet 部分 (繼承得來) │
│ - name: "歐歐" ← private │
│ - health: 95 ← private │
│ - love: 0 ← private │
├─────────────────────────────────────┤
│ Dog 部分 (自有) │
│ - strain: "雪納瑞" ← private │
└─────────────────────────────────────┘
子類對象 = 父類字段 + 子類字段 (連續內存)
private 字段子類不可直接訪問,只能通過父類 public/protected 方法
Pet petRef = new Dog("大黃", "拉布拉多");
│
├─ 編譯類型: Pet → 只能調用 Pet 定義的方法
├─ 運行類型: Dog → 實際執行 Dog 繼承/重寫的方法
└─ petRef.print() → 動態綁定 → 執行 Pet.print() (Dog 未重寫)
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
super.name = name; 在子類構造器中 | private 字段不可見 | 調用 super(name) 讓父類初始化 |
子類構造器未調用 super() | 父類無無參構造器時報錯 | 顯式調用帶參 super(...) |
petRef.getStrain() | 父類引用不可訪問子類方法 | 向下轉型 ((Dog)petRef).getStrain() (需 instanceof 守衛) |
子類定義同名 private 方法 | 不構成重寫,父類方法被隱藏 | 重寫方法權限 ≥ 父類,通常 public/protected |
extends 建立繼承,子類獲得父類非 private 成員。private 字段/方法封裝在父類,子類通過公共 API 間接訪問。設計原則:繼承表達「is-a」關係,
Dog is a Pet成立才用繼承。若只是為復用代碼,請用組合。