Java中的訪問控制權限

簡介

Java中爲何要設計訪問權限控制機制呢?主要做用有兩點:java

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

(2)爲了讓類庫設計者可用更改類的內部工做方式,而沒必要擔憂會對用戶形成重大影響。函數

 

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

Public -> protected -> 包訪問權限(沒有權限修飾詞)-> private設計

 

(package)

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

 

代碼組織

編寫一個Java源代碼文件(.java文件)時,此文件一般被稱爲編譯單元。在編譯單元內最多容許有一個public類,且該類的名稱必須與文件名徹底相同(包括大小寫)。繼承

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

類庫其實是一組類文件。其中每一個.java文件最多容許有一個public類,以及任意數量的非public類。所以,每一個文件都有一個構件。若是要將這些構件(每一個構建有一個.java文件和若干個.class文件)組織起來,造成不一樣的羣組,可使用Java中的關鍵字packageci

 

(package)的做用

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

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

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

 

建立包

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

語法格式:

package pkg1[pkg2[pkg3…]];

注意點:

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

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

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

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

(5)     package的名字通常全是小寫字母。

例如:

查看java.util.ArrayList類的源碼能夠看到文件第一行代碼爲:

package java.util;

它的代碼目錄結構就是java/util/ArrayList.java

 

導入包

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

語法格式:

import package1[.package2…].(classname|*);

例:

仍是以java.util.ArrayList來舉例。若是以一個了類完整路徑的方式來使用它,十分不方便。

java.util.ArrayList<String> list = new java.util.ArrayList<String>();

若是想要省略前面的路徑,可使用import關鍵字。

import java.util.ArrayList;

文件中使用了import導入包後,前面的聲明list的代碼就能夠簡化以下:

ArrayList<String> list = new ArrayList<String>();

 

 

訪問權限修飾詞

package:包訪問權限

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

默認訪問權限沒有任何關鍵字,但一般是指包訪問權限(有時也表示爲friendly,有點像C++中的友元概念)。這意味着包中全部其餘類均可以訪問這個成員或方法,可是這個包以外的全部類不能夠訪問

例:

com.notes.packages.test.Info

package com.notes.packages.test;

publicclass Info {

    void print() { System.out.println("default method -- print()"); }

}

 

com.notes.packages.test.PublicDemo01

package com.notes.packages.test;

publicclass PublicDemo01 {

    publicstaticvoid main(String[] args) {

        Info x = new Info();

        x.print();

    }

}

PublicDemo01Info在同一個包下,能夠訪問Infodefault級別的方法——print()

 

com.notes.packages.PublicDemo02

package com.notes.packages;

import com.notes.packages.test.Info;

publicclass PublicDemo02 {

    publicstaticvoid main(String[] args) {

        Info x = new Info();

        // x.print(); // Error

    }

}

PublicDemo02Info不在一個包下,不能夠訪問Info包訪問權限級別的方法——print()

 

public:接口訪問權限

使用public關鍵字,就意味着被聲明的成員或方法對全部人都是能夠訪問的

例:若是將default級別權限例子中的print()方法權限設爲public,則PublicDemo02能夠訪問。

package com.notes.packages.test;

publicclass Info {

    publicvoid print() { System.out.println("public method -- print()"); }

}

 

private:沒法訪問

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

應用場景:單例模式

 

protected:繼承訪問權限

新類(稱之子類或派生類)經過繼承能夠複用一個現有類(稱之父類或基類),而後擴展基類的成員、方法。有時,基類的建立者會但願某個特定成員,將它的訪問權限賦予派生類而不是全部類。public沒法作到這一點,爲此,引入了protected來完成這一工做。protected也提供包訪問權限,也就是說,派生類以及相同包內的其餘類均可以訪問protected成員或方法

例:子類繼承父類後,能夠訪問父類的protected成員。

class Father {

    private String a = "private";

    protected String b = "protected";

    public String c = "public";

};

 

class Son extends Father {

    publicvoid print() {

        // System.out.println("element a" + super.a); // Error

        System.out.println("element b" + super.b);

        System.out.println("element c" + super.c);

    }

}

 

publicclass ProtectedDemo01 {

    publicstaticvoid main(String args[]) {

        Son sub = new Son();

        sub.print();

    }

};

 

訪問權限修飾詞的注意點

前面各個例子中展現了類的成員、方法均可以用各類權限修飾詞來修飾。

除此以外,還有一些須要注意的點:

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

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

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

相關文章
相關標籤/搜索