「封裝」常被簡化為「資料隱藏」,但其真正核心是**介面與實作的分離**。Java 的存取控制機制(public/protected/package-private/private)正是為了在語言層面強制實現這一分離。本文將從設計哲學、類別定義策略、工具支援三個維度闡述這一核心機制。
public,用戶只見真正需要的介面public 介面不變,內部任何調整(資料結構換、演算法優化、Bug 修復)都不需用戶修改代碼第二點是封裝的**戰略價值**:它賦予庫設計者「安全犯錯、大膽重構」的自由。
在 Java 中,class 關鍵字定義的是一種**新資料型別**(如 Fish、Bird),而非單純的資料容器。所有屬於此類別的物件共享:
這正是為什麼 class 是整個語言的核心關鍵字(本書不加粗體即因太常見)。
建議在類別原始碼中按存取層級分組排序:
public class X {
// 1. public 介面:用戶最關心,放最前面
public void pub1() { ... }
public void pub2() { ... }
public void pub3() { ... }
// 2. protected:子類別擴充點
protected void prot1() { ... }
// 3. package-private:套件內協作
void pkg1() { ... }
// 4. private 實作細節:最後,用戶無需閱讀
private void impl1() { ... }
private void impl2() { ... }
private int internalState;
// ...
}
好處:用戶由上往下讀,看到非 public 即可停止,專注於介面契約。
原始碼畢竟混雜實作細節。**真正的介面呈現交給工具**:
public/protected 成員的 HTML 文件,含說明、參數、回傳值、異常等契約資訊現代 Java 開發環境(IntelliJ、Eclipse、VS Code)皆內建優秀的類別瀏覽器,讓「介面與實作分離」在工具層面完美落地。
| 場景 | 無分離(全 public) | 有分離(存取控制) |
|---|---|---|
| 內部資料結構調整 | 用戶代碼直接存取欄位 → 必須同步修改 | 用戶只呼叫方法 → 內部換 ArrayList 改 HashMap 零影響 |
| 演算法優化 | 用戶可能依賴副作用/執行順序 → 風險極高 | 只保證契約(輸入/輸出/異常) → 任意優化 |
| Bug 修復 | 修復可能破壞用戶隱性依賴 | 只修私有方法,public 行為不變 → 安全 |
| 新增功能 | 隨意加 public 方法 → 介面膨脹 | 新增 private 輔助,public 只加真正需要的 → 介面精簡 |
Java 存取控制不是為了「防禦惡意用戶」,而是為了**明確劃分契約邊界**:
public = **契約**(承諾穩定、文件化、向後相容)private/package-private/protected = **實作自由區**(可任意變更、重構、優化)嚴守這條界線,你的類別庫將同時擁有:用戶友善的清晰介面、開發者享有的重構自由、系統具備的長期演進能力。這才是物件導向封裝的工程學本質。