首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java protected 關鍵字深度解析:繼承與套件存取的橋樑

     編輯:Java 相關知識

protected 是 Java 四大存取修飾詞中最獨特、也最常被誤解的一個。它結合了「套件可見」與「子類別可見」兩種語意,專為**繼承體系**設計。本文將透過程式碼示範其精確存取規則、與 package-private 的差異,以及實務應用場景。

protected 精確存取規則

protected 成員可被存取的條件(滿足任一即可):

  1. 同一套件內的任意類別(同 package-private)
  2. 不同套件的子類別**(繼承關係)

換句話說:protected = package-private + 子類別存取權。

程式碼示範:跨套件繼承的存取差異

基底套件:c05.dessert

// Cookie.java
package c05.dessert;

public class Cookie {
    public Cookie() { System.out.println("Cookie constructor"); }
    void foo() { System.out.println("foo"); }  // package-private
}

衍生類別在不同套件:ChocolateChip

// ChocolateChip.java
import c05.dessert.*;

public class ChocolateChip extends Cookie {
    public ChocolateChip() { System.out.println("ChocolateChip constructor"); }
    public static void main(String[] args) {
        ChocolateChip x = new ChocolateChip();
        // x.foo();  // 編譯錯誤:foo() 是 package-private,跨套件子類別不可見
    }
}

結果:ChocolateChip 雖繼承 Cookie,但因在不同套件,**無法存取** foo()。

將 foo() 改為 protected

// Cookie.java 修改版
public class Cookie {
    public Cookie() { System.out.println("Cookie constructor"); }
    protected void foo() { System.out.println("foo"); }  // 改為 protected
}

現在:

  • 同套件 c05.dessert 內類別:仍可存取 foo()(protected 包含套件可見)
  • 不同套件子類別 ChocolateChip:**可存取** foo()
  • 不同套件非子類別:仍**不可存取**(非 public)

protected vs 其他修飾詞對照

修飾詞同套件不同套件子類別不同套件非子類別典型用途
private✗✗✗類別內部實作
package-private✓✗✗套件內協作、內部實作
protected✓✓✗**給子類別的擴充點/鉤子**
public✓✓✓對外公開介面

設計意圖:為子類別保留「受控擴充權」

protected 存在的核心理由:**基底類別設計者希望子類別能存取/覆寫特定內部機制,但不想對全世界公開**。典型場景:

  • 模板方法模式:基底類別定義演算法骨架,關鍵步驟宣告 protected abstract,強制子類別實作
  • 內部狀態存取:子類別需直接讀寫基底類別的特定欄位(如 protected int state),避免 getter/setter 開銷
  • 覆寫鉤子:protected void onInit() {} 讓子類別選擇性擴充初始化邏輯

常見誤區與最佳實務

  1. 誤區:protected 欄位破壞封裝 → 正確:protected 針對「繼承關係」開放,比 public 窄得多,是刻意設計的擴充點
  2. 建議:優先用 private + protected 方法(而非欄位)給子類別,保留未來改變資料結構的彈性
  3. 建議:若無繼承需求,**不要用 protected**,直接用 private 或 package-private
  4. 文件化:在 JavaDoc @see 或說明中標註:「供子類別覆寫/存取,用於 XXX 目的」

總結

protected 是繼承體系的「特權通道」:它比 package-private 寬(跨套件子類別可見),比 public 窄(非子類別不可見)。善用它能在「封裝內部細節」與「提供擴充彈性」之間取得最佳平衡,是設計可擴充框架的關鍵工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved