天天看點

Java 通路控制權限一、介紹二、詳解三、總結

一、介紹

通路控制權限控制用戶端對類的通路權限,提供給用戶端不同權限的接口,對整個程式結構和接口與實作都進行支援。

二、詳解

1、包

包(Package)基本上寫過java語言都熟悉package是什麼。package的主要作用,是對類提供一個命名空間。程式員可以将多個類檔案放置到同一個package下來組織這些類檔案關系。我們可以說一個類是由package+className實作了一個類的唯一标示。

(1)包的聲明與使用

因為一個類的可以說是由package加上類檔案組成,是以我們在定義一個類是需要類的包定名,也就是給類聲明一個命名空間。是以我們在類的第一行代碼進行包聲明:

包在聲明過程中,需要注意的點:

1、使用關鍵字package聲明Java類的package

2、package的聲明過程中全部小寫

3、package當出現層次關系式,使用點來表示,子封包件夾

當我們使用一個已經定義好的類是,需要使用類全限定名(package + classname)來引入一個類檔案。當然我們也可以批量引入某一個包中的所有類。

import com.wozipa.study.java.access.PackageTests;
import com.wozipa.study.java.access.*;
           

(2)包在類加載時的作用

我們在開發過程中,編譯後一個類檔案中所有的類定義都會生成一個.class檔案,最終我們會将所有的.class檔案打包生成一個Jar檔案。

當我們在使用一個Jar檔案時,首先需要将該Jar至于CLASSPATH環境變量中,JVM虛拟機會自動解析CLASSPATH變量中所有的Jar檔案,當load一個class檔案時,就會從這些CLASSPATH變量中的Jar檔案中擷取類檔案。類加載器會根據一個類的package,将其轉換成相應的檔案夾層次關系,例如com.wozipa.study.java.access會轉換成com/wozipa/study/java/access,從CLASSPATH的根路徑下沿着檔案夾層次關系進行查找。

(3)沖突

有時我們會使用兩個相同類名稱的類,在代碼編寫過程中就會出現類名沖突,就是說使用這個類名時,編譯器不知道該類名指向的是哪一個類檔案。這種情況下我們需要通過類的全限定名來告知編譯器類的具體路徑:

例如下面,當我們使用第二個PackageTests時,需要通過指定全限定名稱來指出類的位置。

import com.wozipa.study.java.access.PackageTests;

public class DefaultTests {
    public static void main(String[] args)
    {
    PackageTests tests = new PackageTests();
    com.wozipa.study.java.nio.PackageTests tests1 = new com.wozipa.study.java.nio.PackageTests();
    }
}
           

2、Java通路修飾符

Java通路修飾符通過修飾類、屬性、方法、構造器等,來控制所修飾的實體的通路權限。Java的通路修飾符一共四個:private、friendly(包預設權限,預設權限),protected和public。

(1)friendly

包通路權限,顧名思義,就是指當一個屬性或者方法(包括構造器方法)使用該權限修飾時,這個屬性或者方法可以被同一個Package内的其他類直接使用,而其他Package的類将無法直接該屬性或者方法。

(2)public

公開通路權限,被public權限修飾符修飾的屬性或者方法函數(包括構造器函數)可以被其他任意的用戶端程式進行直接通路。

(3)private

私有權限,被private修飾的屬性或者方法函數隻能在本類(而不是類檔案,也就是說類檔案中的 其他類也沒辦法直接通路該類的私有屬性或方法)中使用。

例子:當我們對構造函數用private修飾時,其他類就無法通過new方式來建立對象,如果排除反射,這個基本無法被别人初始化,通過這個原理就有了單例模式:

public class Singletom {

    public static Singletom singletom = null;

    public static Singletom getSingletom()
    {
        if(singletom == null)
        {
            singletom = new Singletom();
        }
        return singletom;

    }
    private Singletom(){}
}
           

這裡的單例模式隻是簡單的說明實作原理,完整的單例模式需要更負責的代碼,後面會總結單例模式的多種實作方式。

(4)protected

繼承關系權限,被protected修飾的屬性或者方法能夠被子類或者同一個Package的類使用。也就是說protected除了繼承關系權限外,還具有包通路權限。

注意:子類中定義的protected,父類無法使用。

(5)通路手段

想要通路一個屬性或者方法是,隻能通過一下手段:

(1)将該屬性或者方法定義為public權限,用戶端可以直接通路和使用

(2)将屬性和方法定義為protected方法,可以被子類或者同一個Package的類使用。

(3)對屬性或方法使用預設權限,同一個Package内的其他類能夠被使用。

(4)對屬性使用私有方法使,使用通路器(getter)和變異器(setter)進行屬性的擷取和變更

(6)預設包的權限

當一個類在聲明時沒有通過package關鍵字添加包定義,那麼這個類就會存在預設包中,而從JDK1.4開始,預設包的中的将無法直接被通路和使用,即預設包中的類即使是public修飾,使用者依舊沒有辦法擷取該類的通路。如果想使用預設包中的類時,必須使用反射技術去擷取該對象的執行個體:

public class DefaultTests {

    private String name ="default package tests";

    @Override
    public String toString() {
        return name;
    }
}
           
public static void main(String[] args)
{
    try {
       Class clazz = Class.forName("DefaultTests");
       System.out.print(clazz.newInstance().toString());
    } catch (ClassNotFoundException e) {
            e.printStackTrace();
    } catch (IllegalAccessException e) {
            e.printStackTrace();
    } catch (InstantiationException e) {
            e.printStackTrace();
    }
}
           

3、接口與實作

通路控制權限經常被稱為具體實作的隐藏。把資料和方法包裝到類中,以及具體實作的隐藏,通常共同成為封裝。從這句話中,封裝不簡單的包裝,而且還有具體屬性和方法的通路控制。這樣的原因有兩個:

(1)我們通過通路控制來定義用戶端程式可以通路和不可通路的權限,用戶端程式隻能通路特定的接口,而邏輯的具體實作通過不可通路全向封裝在内部。防止用戶端通路一些邏輯内的函數。

(2)通過通路控制權限,用戶端隻能通路特定接口,當具體實作發生改變時,并不會對用戶端程式的接口通路産生任何影響。

是以我們可以總結為:我們通過權限控制,向用戶端程式開放特定接口,然後将内部具體實作通過控制權限封裝在内部,這樣既可以保證用戶端程式不會調用不該調用的接口,還可以在内部實作修改時,不會影響到用戶端程式。

4、類的通路權限

我們在前面對通路控制進行講解時,對象都是屬性或者方法,下面介紹一下類的通路權限控制。

(1)類檔案

1、一個類檔案中,允許一個權限為public的類聲明和多個預設權限的類聲明。

2、類檔案中的public修飾的類聲明的名稱必須與類檔案的名稱相同,包括大小寫

3、類檔案可以隻聲明多個預設權限的類,并且名字不需要與類檔案名稱相同。

(2)類的權限

類在聲明時,隻有public和預設權限這兩種,沒有protected和private。

當我們在将類定義為預設包權限時,類内部的屬性和方法的通路權限也就是預設權限,即使是定義了public,也隻能被同一個包中的其他類使用。

三、總結

如果有什麼錯誤的地方請幫我指明出來,共勉!