Java訪問控制修飾符詳解(public、 private、protected 和 friendly)

在 Java 語言中提供了多個作用域修飾符,其中常用的有 public、private、protected、final、abstract、static、transient 和 volatile,這些修飾符有類修飾符、變量修飾符和方法修飾符。本文將詳細介紹訪問控制修飾符。

在實際生活中,如果要獲取某件物品,與其直接穿過堡壘的牆壁,從而導致牆壁毀滅和破壞,不如通過門口的警衛請求進入堡壘的許可。一般而言,這對對象同樣適用:沒有對象的許可(即對象的屬性是私有的),不能直接訪問該對象的私有屬性。

信息隱藏是 OOP 最重要的功能之一,也是使用訪問修飾符的原因。在編寫程序時,有些核心數據往往不希望被用戶調用,需要控制這些數據的訪問。

對類成員訪問的限制是面向對象程序設計的一個基礎,這有利於防止對象的誤用。只允許通過一系列定義完善的方法來訪問私有數據,就可以(通過執行範圍檢查)防止數據賦予不正當的值。例如,類以外的代碼不可能直接向一個私有成員賦值。同時,還可以精確地控制如何以及何時使用對象中的數據。

當正確實現對類成員的方法控制後,類就可以創建一個可用的“黑箱”,其內部動作不會被打開而任意篡改。

通過使用訪問控制修飾符來限制對對象私有屬性的訪問,可以獲得 3 個重要的好處。

  • 防止對封裝數據的未授權訪問。
  • 有助於保證數據完整性。
  • 當類的私有實現細節必須改變時,可以限制發生在整個應用程序中的“連鎖反應”。


訪問控制符是一組限定類、屬性或方法是否可以被程序裏的其他部分訪問和調用的修飾符。類的訪問控制符只能是空或者 public,方法和屬性的訪問控制符有 4 個,分別是 public、 private、protected 和 friendly,其中 friendly 是一種沒有定義專門的訪問控制符的默認情況。訪問控制修飾符的權限如表 1 所示。
 

表1 各種訪問修飾符的可訪問性
訪問範圍 private friendly(默認) protected public
同一個類 可訪問 可訪問 可訪問 可訪問
同一包中的其他類 不可訪問 可訪問 可訪問 可訪問
不同包中的子類 不可訪問 不可訪問 可訪問 可訪問
不同包中的非子類 不可訪問 不可訪問 不可訪問 可訪問


訪問控制在面向對象技術中處於很重要的地位,合理地使用訪問控制符,可以通過降低類和類之間的耦合性(關聯性)來降低整個項目的複雜度,也便於整個項目的開發和維護。在 Java 語言中,訪問控制修飾符有 4 種。

1. private

用 private 修飾的類成員,只能被該類自身的方法訪問和修改,而不能被任何其他類(包括該類的子類)訪問和引用。因此,private 修飾符具有最高的保護級別。例如,設 PhoneCard 是電話卡類,電話卡都有密碼,因此該類有一個密碼域,可以把該類的密碼域聲明爲私有成員。

2. friendly(默認)

如果一個類沒有訪問控制符,說明它具有默認的訪問控制特性。這種默認的訪問控制權規定,該類只能被同一個包中的類訪問和引用,而不能被其他包中的類使用,即使其他包中有該類的子類。這種訪問特性又稱爲包訪問性(package private)。

同樣,類內的成員如果沒有訪問控制符,也說明它們具有包訪問性,或稱爲友元(friend)。定義在同一個文件夾中的所有類屬於一個包,所以前面的程序要把用戶自定義的類放在同一個文件夾中(Java 項目默認的包),以便不加修飾符也能運行。

3. protected

用保護訪問控制符 protected 修飾的類成員可以被三種類所訪問:該類自身、與它在同一個包中的其他類以及在其他包中的該類的子類。使用 protected 修飾符的主要作用,是允許其他包中它的子類來訪問父類的特定屬性和方法,否則可以使用默認訪問控制符。

4. public

當一個類被聲明爲 public 時,它就具有了被其他包中的類訪問的可能性,只要包中的其他類在程序中使用 import 語句引入 public 類,就可以訪問和引用這個類。

類中被設定爲 public 的方法是這個類對外的接口部分,避免了程序的其他部分直接去操作類內的數據,實際就是數據封裝思想的體現。每個 Java 程序的主類都必須是 public 類,也是基於相同的原因。

例 1

下面來創建一個示例,演示 Java 中訪問控制修飾符的使用。

(1) 新建 Student.java 文件,在該文件中定義不同修飾符的屬性和方法,代碼如下:


 
  1. class Student {
  2. // 姓名,其訪問權限爲默認(friendly)
  3. String name;
  4.  
  5. // 定義私有變量,身份證號碼
  6. private String idNumber;
  7.  
  8. // 定義受保護變量,學號
  9. protected String no;
  10.  
  11. // 定義共有變量,郵箱
  12. public String email;
  13.  
  14. // 定義共有方法,顯示學生信息
  15. public String info() {
  16. return"姓名:"+name+",身份證號碼:"+idNumber+",學號:"+no+",郵箱:"+email;
  17. }
  18. }

(2) 新建 StudentTest.java 文件,在該文件中定義 main() 方法,訪問 Student 類中的屬性並賦值,打印出用戶的信息。代碼如下:


 
  1. public class StudentTest {
  2. public static void main(String[] args) {
  3. // 創建Student類對象
  4. Student stu = new Student();
  5. // 向Student類對象中的屬性賦值
  6. stu.name = "zhht";
  7.  
  8. // stu.idNumber="043765290763137806";
  9. // 這是不允許的。提示stu.idNumber是不可見的,必須註釋掉纔可運行
  10. stu.no = "20lil01637";
  11. stu.email = "[email protected]";
  12. System.out.println(stu.info());
  13. }
  14. }

在 StudentTest 類中,“stu.idNumber="043765290763137806";”代碼行將提示 “The field User.password is not visible”錯誤信息。將該代碼行註釋掉再運行 StudentTest.java 文件,輸出的內容如下:

姓名:zhht,身份證號碼:null,學號:20lil01637,郵箱:[email protected]


在源文件中創建了兩個類,分別爲主類 StudentTest 和輔助類 Student,二者在同一個包中。

在輔助類 Student 中,創建了 4 個屬性,其訪問控制分別爲默認的、私有的、受保護的和共有的,除了私有控制符修飾的變量之外,其他的都可以被主類訪問,同時創建了一個共有的方法——info(),用於打印用戶信息。

在主類 StudentTest 中,創建類 Student 的實例化對象 stu,通過對象 stu 來訪問該對象中的屬性並賦值,因爲 idNumber 屬性的修飾符爲 private(私有的),因此,在 StudentTest 類中的 main() 方法中無法訪問該屬性。

從上面的例子中可以看出,範圍控制修飾符成功地限制了訪問者訪問不同修飾符的屬性(成員變量),從而實現了數據的隱藏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章