| 修飾對象 | 語法 | 語意 | 限制 |
|---|---|---|---|
| 類 | abstract class Animal {} | 半成品,不可實例化,供繼承 | 不可 new,可作為型別宣告 |
| 方法 | abstract void move(); | 僅宣告簽名,無實現(無大括號) | 子類必須覆寫(除非子類也是 abstract) |
| 維度 | 抽象類 | 介面 |
|---|---|---|
| 關鍵字 | extends(單繼承) | implements(多實現) |
| 關係語意 | is-a(繼承關係) | like-a / capable-of(能力契約) |
| 成員變數 | 任意:實例/靜態、final/非 final | 僅 static final 常數 |
| 建構子 | 可有(供子類 super() 呼叫) | 無 |
| 方法實現 | 可混合抽象/具體/private/static | JDK 7-:全抽象;JDK 8+:default/static/private |
| 演化成本 | 低(新增具體方法不影響子類) | 高(JDK 7- 新增方法破壞所有實現) |
| 型別組合 | 單一繼承鏈 | 多介面任意組合 |
// 抽象類:定義門的核心骨架
abstract class Door {
abstract void open();
abstract void close();
// 可提供共用邏輯
void lock() { System.out.println("門已鎖定"); }
void unlock() { System.out.println("門已解鎖"); }
}
// 介面:定義報警能力契約
interface Alarm {
void alarm();
}
// 具體實現:組合兩者
class AlarmDoor extends Door implements Alarm {
@Override
public void open() { System.out.println("報警門開啟"); }
@Override
public void close() { System.out.println("報警門關閉"); }
@Override
public void alarm() { System.out.println("警報觸發!"); }
}
// 普通門:僅繼承抽象類
class NormalDoor extends Door {
@Override public void open() { System.out.println("普通門開啟"); }
@Override public void close() { System.out.println("普通門關閉"); }
}
// 1. 介面定義完整契約(頂層)
public interface EventListener {
void onStart();
void onProgress(int percent);
void onComplete();
void onError(Exception e);
}
// 2. 抽象類提供預設實現(中間層)
public abstract class AbstractEventListener implements EventListener {
@Override public void onStart() { /* 預設空 */ }
@Override public void onProgress(int percent) { /* 預設空 */ }
@Override public void onComplete() { /* 預設空 */ }
@Override public void onError(Exception e) {
e.printStackTrace(); // 預設記錄錯誤
}
}
// 3. 業務類靈活選擇
public class SimpleListener extends AbstractEventListener {
@Override public void onComplete() {
System.out.println("任務完成"); // 僅關心完成事件
}
}
// 或直接實現介面(需全實現)
public class FullListener implements EventListener { /* 全部實現 */ }
JDK 命名慣例:AbstractList、AbstractMap、AbstractExecutorService、AbstractQueuedSynchronizer。
// ✅ 正確:宣告用介面/抽象型別
List list = new ArrayList<>();
Map cache = new ConcurrentHashMap<>();
Runnable task = () -> System.out.println("Run");
Comparator byAge = Comparator.comparing(User::getAge);
// ❌ 錯誤:宣告洩漏具體實現
ArrayList list = new ArrayList<>();
HashMap cache = new HashMap<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(...);
Serializable & Cloneable & Comparable) → 介面record (JDK 14+)誤區:「介面不能有實現,功能較弱」
→ JDK 8
default方法賦予介面實現能力,但語意不同:介面實現是「預設行為」,抽象類實現是「共享骨架」。
誤區:「繼承抽象類就不能實現介面」
→ Java 支援
class A extends Base implements I1, I2,單繼承 + 多實現。
誤區:「所有類都要抽取介面」
→ 違反 YAGNI 原則。僅對「需替換、需 Mock、跨邊界」的類抽取介面。
abstract 定義「未完成的類/方法」,強制子類補全。介面定義契約(做什麼),抽象類提供骨架(怎麼做)。架構分層:介面(頂層契約) → 抽象類(中間骨架) → 具體類(葉子實現)。掌握此層次,才是真正掌握面向物件設計精髓。