訪問控制權限


一、簡介

Java中為什么要設計訪問權限控制機制呢?主要作用有兩點:

(1)為了使用戶不要觸碰那些他們不該觸碰的部分,這些部分對於類內部的操作時必要的,但是它並不屬於客戶端程序員所需接口的一部分。

(2)為了讓類庫設計者可用更改類的內部工作方式,而不必擔心會對用戶造成重大影響。

Java中的訪問權限控制的等級,按照權限從大到小依次為

public -> protected -> 包訪問權限(沒有權限修飾詞)-> private。

二、包(package)

Java中包(package)的概念和C++中命名空間(namespace)的概念很類似,都可以限制類的作用域。二者最大的差別在於,Java中的包隱式地指明了類的樹形層級結構(同時也是Java源碼文件的目錄結構)。這樣做的好處在於:可以通過文件系統中對於文件路徑唯一性的要求來限制類的唯一性。

1. 代碼組織

編寫一個Java源代碼文件(.java文件)時,此文件通常被稱為編譯單元。在編譯單元內最多允許有一個public類,且該類的名稱必須與文件名完全相同(包括大小寫)。

編譯一個.java文件時,在.java文件中的每個類都會有一個.class輸出文件,這個文件名和類名是相同的。Java可運行程序是一組可以打包並壓縮為一個Java文檔文件(JAR包,使用Java的jar文檔生成器)的.class文件。Java解釋器負責這些文件的查找、裝載和解釋。

類庫實際上是一組類文件。其中每個.java文件最多允許有一個public類,以及任意數量的非public類。因此,每個文件都有一個構件。如果要將這些構件(每個構建有一個.java文件和若干個.class文件)組織起來,形成不同的群組,可以使用Java中的關鍵字package

2. 包(package)的作用

(1) 把功能相似或相關的類或接口組織在同一個包中,方便類的查找和使用。

(2) 如同文件夾一樣,包也采用了樹形目錄的存儲方式。同一個包中的類名字是不同的,不同的包中的類的名字是可以相同的,當同時調用兩個不同包中相同類名的類時,應該加上包名加以區別。因此,包可以避免名字沖突。

(3) 包也限定了訪問權限,擁有包訪問權限的類才能訪問某個包中的類。

3. 創建包

Java中,使用package關鍵字來指定代碼所屬的包(命名空間)。

語法格式:package pkg1[.pkg2[.pkg3…]];

注意點:

(1)  包的名字隱含地指出了代碼的目錄結構。

(2)  同一目錄下的public類名(同時也是java文件名)應該是獨一無二的。

(3)  包聲明應該在源文件的第一行,每個源文件只能有一個包聲明,這個文件中的每個類型都應用於它。

(4)  如果一個源文件中沒有使用包聲明,那么其中的類,函數,枚舉,注釋等將被放在一個無名的包(unnamed package)中。

(5) package的名字一般全是小寫字母。

4. 導入包

Java中,使用import關鍵字來導入包。

三、訪問權限修飾詞

1. package:包訪問權限

如果不提供任何訪問權限修飾詞,則意味着它是包訪問權限

默認訪問權限沒有任何關鍵字,但通常是指包訪問權限(有時也表示為friendly,有點像C++中的友元概念)。這意味着包中所有其他類都可以訪問這個成員或方法,但是這個包之外的所有類不可以訪問

示例:

package com.notes.packages.test;

public class Info {
    void print() { System.out.println("default method -- print()"); }
}
package com.notes.packages.test;

public class PublicDemo01 {
    public static void main(String[] args) {
        Info x = new Info();
        x.print();
    }
}

PublicDemo01和Info在同一個包下,可以訪問Info的default級別的方法——print()。

package com.notes.packages;
import com.notes.packages.test.Info;
public class PublicDemo02 {
    public static void main(String[] args) {
        Info x = new Info();
        // x.print(); // Error
    }
}

PublicDemo02和Info不在一個包下,不可以訪問Info的包訪問權限級別的方法——print()。

2. public接口訪問權限

使用public關鍵字,就意味着被聲明的成員或方法對所有人都是可以訪問的

例:如果將default級別權限例子中的print()方法權限設為public,則PublicDemo02可以訪問。

package com.notes.packages.test;
public class Info {
    public void print() { System.out.println("public method -- print()"); }
}
3. private:私有訪問

使用private關鍵字,就意味着被聲明的成員或方法,除了本類,其他任何類都無法訪問

應用場景:單例模式

4. protected:繼承訪問權限

新類(稱之子類或派生類)通過繼承可以復用一個現有類(稱之父類或基類),然后擴展基類的成員、方法。有時,基類的創建者會希望某個特定成員,將它的訪問權限賦予派生類而不是所有類。public無法做到這一點,為此,引入了protected來完成這一工作。protected也提供包訪問權限,也就是說,派生類以及相同包內的其他類都可以訪問protected成員或方法

例:子類繼承父類后,可以訪問父類的protected成員。

class Father {
    private String a = "private";
    protected String b = "protected";
    public String c = "public";
};

class Son extends Father {
    public void print() {
        // System.out.println("element a:" + super.a); // Error
        System.out.println("element b:" + super.b);
        System.out.println("element c:" + super.c);
    }
}

public class ProtectedDemo01 {
    public static void main(String args[]) {
        Son sub = new Son();
        sub.print();
    }
};

四、訪問權限修飾詞的注意點

(1) 靜態成員、靜態方法的權限修飾詞的用法和普通成員、方法一樣。

(2) 類雖然也可以被修飾詞修飾,但是不可以用privateprotected兩個權限修辭詞。

(3) 有些書中將包訪問權限又叫做默認訪問權限。個人不建議這么去記,因為這很容易與Java Se8中新特性——default關鍵字混淆。這個關鍵字只能用於Interface,作用是允許程序員在Interface中定義接口的默認具體實現(以往的JDK版本是不允許這樣的,你只能在接口中聲明方法)。

 

參考

https://www.cnblogs.com/jingmoxukong/p/5182331.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM