一、介紹
通路控制權限控制用戶端對類的通路權限,提供給用戶端不同權限的接口,對整個程式結構和接口與實作都進行支援。
二、詳解
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,也隻能被同一個包中的其他類使用。
三、總結
如果有什麼錯誤的地方請幫我指明出來,共勉!