一、從現實到代碼:抽象的概念¶
想象一下,我們去動物園看到各種動物:貓、狗、鳥。它們都屬於“動物”這個大類,有共同的特徵(比如會呼吸、有生命),但具體行爲不同(貓“喵喵”叫,狗“汪汪”叫,鳥“喳喳”叫)。
在Java中,我們可以把“動物”抽象成一個模板,這個模板包含所有動物的共同特徵(比如“會叫”),但不具體實現“怎麼叫”——因爲不同動物叫的方式不一樣。這個模板就是抽象類,而“怎麼叫”就是抽象方法(只定義“要做什麼”,不定義“怎麼做”)。
二、爲什麼要定義抽象類?¶
抽象類的核心作用是提供通用模板,同時限制子類必須實現某些方法。具體來說有3個原因:
- 統一行爲規範:比如所有動物都要“叫”,抽象類規定“必須有叫的方法”,子類不能隨便省略,保證代碼風格一致。
- 避免不完整對象:抽象類本身不能直接創建對象(比如“動物”本身不存在,只有具體的貓、狗才存在),強制子類去實現細節,避免創建功能缺失的對象。
- 代碼複用:抽象類可以包含通用屬性和方法(比如所有動物都有“年齡”屬性,“喫飯”方法),子類直接繼承,不用重複寫代碼。
三、基礎語法解析¶
1. 定義抽象類¶
用 abstract 關鍵字修飾類,語法格式:
abstract class 類名 {
// 抽象方法(只聲明,無實現)
public abstract void 方法名();
// 非抽象方法(可以有具體實現)
public void 通用方法() {
System.out.println("這是通用方法");
}
}
注意:
- 抽象類可以有普通屬性(比如 int age;)和非抽象方法。
- 抽象類不能被 new 直接實例化(比如 new 抽象類名() 是錯誤的),只能被子類繼承。
2. 定義抽象方法¶
用 abstract 關鍵字修飾方法,語法格式:
public abstract void 方法名(); // 只有聲明,沒有大括號和具體邏輯
注意:
- 抽象方法必須由子類實現(除非子類也是抽象類)。
- 抽象方法不能是 private(子類無法訪問私有方法),也不能是 static(static 方法屬於類,而抽象方法無實現,矛盾)。
3. 子類繼承抽象類¶
子類必須實現抽象類中所有的抽象方法,否則子類也必須聲明爲抽象類。語法示例:
// 抽象類:動物
abstract class Animal {
public abstract void makeSound(); // 抽象方法:叫什麼聲(未實現)
public void eat() { // 非抽象方法:喫飯(具體實現)
System.out.println("動物在喫飯");
}
}
// 子類:狗(繼承Animal)
class Dog extends Animal {
// 必須實現抽象方法makeSound()
@Override
public void makeSound() {
System.out.println("汪汪汪!");
}
}
// 子類:貓(繼承Animal)
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵!");
}
}
四、示例代碼:用抽象類實現“動物叫”¶
// 抽象類:動物
abstract class Animal {
// 抽象方法:規定子類必須實現“叫”的行爲
public abstract void makeSound();
// 非抽象方法:所有動物都會喫飯(通用實現)
public void eat() {
System.out.println("動物正在喫飯");
}
}
// 子類:狗
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("狗:汪汪汪!");
}
}
// 子類:貓
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("貓:喵喵喵!");
}
}
// 測試類
public class TestAnimal {
public static void main(String[] args) {
// 只能通過子類實例化(抽象類不能直接new)
Animal dog = new Dog();
Animal cat = new Cat();
dog.makeSound(); // 輸出:狗:汪汪汪!
cat.makeSound(); // 輸出:貓:喵喵喵!
dog.eat(); // 輸出:動物正在喫飯(繼承通用方法)
}
}
五、關鍵點總結¶
- 抽象類定義:用
abstract class聲明,不能實例化。 - 抽象方法:用
abstract聲明,無方法體,子類必須實現。 - 子類規則:非抽象子類必須實現所有抽象方法;抽象子類可繼承抽象方法。
- 通用方法:抽象類可包含普通方法和屬性,子類直接複用。
小提醒:抽象類是“單繼承”的,子類只能繼承一個抽象類,但可以實現多個接口(後續會學)。如果需要強制子類實現某方法,抽象類是更靈活的選擇!