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

深入探討 Java 內部類別的可見性規則

     編輯:Java 相關知識

前言

Java 內部類別實例持有外部類別參考(OuterClass.this),可存取外部類別所有成員(含 private)。但外部類別、同套件其他類別、不同套件類別、繼承類別對內部類別的可見性有何差異?本文透過完整程式碼實測四種內部類別(private、default、protected、public)在四種情境下的存取規則。

測試架構

外部類別 Out 定義四種內部類別,皆實作 InMethod 介面(含 public_method())。每個內部類別擁有四種可見性的欄位與方法。Out 提供 getXxxIn() 回傳內部類別實例。

1. 外部類別本身的存取

兩種建立方式:

  • new Out().new PrivateIn()
  • out.getPrivateIn()

結果:外部類別可建立所有內部類別實例,並存取其所有成員(含 private 欄位/方法)。內部類別對建立它的外部類別實例完全可見。

2. 同套件其他類別(SamePackage)

方式一:out.new Inner()

  • private 內部類別:編譯錯誤,型別不可見
  • default、protected、public:可建立實例,但無法存取內部類別的 private 成員

方式二:out.getPrivateIn()

  • 回傳型別為 PrivateIn 時,同樣編譯錯誤(型別不可見)
  • 利用介面參考 InMethod ref = out.getPrivateIn():可呼叫 public_method()

3. 不同套件類別(DifferPackage)

  • out.new PublicIn() 或 out.getPublicIn():僅能存取 public 內部類別的 public 成員
  • 介面參考 InMethod ref = out.getXxxIn():可呼叫所有內部類別的 public_method()

4. 不同套件繼承類別(DifferPackageExtend extends Out)

  • extend.new ProtectedIn():型別可見,但建構子不可見(編譯錯誤)
  • extend.getProtectedIn():可取得實例,但僅能存取 public 成員

結論:protected 內部類別不受外部類別繼承關係影響,其建構子與成員存取權遵循一般 protected 規則(同套件可見、子類別可見型別但不可實例化)。

總結表

存取者private 內部類別default 內部類別protected 內部類別public 內部類別
外部類別完全可見完全可見完全可見完全可見
同套件類別型別不可見,介面參考可呼叫 public 方法型別可見,無法存取 private 成員型別可見,無法存取 private 成員型別可見,無法存取 private 成員
不同套件類別型別不可見,介面參考可呼叫 public 方法型別不可見型別不可見型別可見,僅能存取 public 成員
不同套件子類別型別不可見,介面參考可呼叫 public 方法型別不可見型別可見,建構子不可見,僅能存取 public 成員型別可見,僅能存取 public 成員

關鍵觀念

  • 內部類別的可見性修飾字控制的是型別本身的可見性,而非其成員存取權
  • private 內部類別對外完全隱藏,只能透過外部類別方法以介面型別回傳
  • protected 內部類別的建構子不可被子類別呼叫,這與一般 protected 方法行為不同
  • 善用介面可繞過型別可見性限制,實現封裝與多型
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved