詳解Java之路(五) 訪問權(quán)限控制
在Java中,所有事物都具有某種形式的訪問權(quán)限控制。
訪問權(quán)限的控制等級從最大到最小依次為:public,protected,包訪問權(quán)限(無關(guān)鍵詞)和private。
public,protected和private這幾個Java訪問權(quán)限修飾詞在使用時,是置于類中每個成員(域或者方法)定義之前的。
一、類成員的訪問權(quán)限
取得對某成員的訪問權(quán)的唯一途徑是:
1).使該成員成為public。無論誰在哪里,都可以訪問該成員;
2).通過不加訪問權(quán)限的修飾詞并將其他類放置于同一包內(nèi)的方式給成員賦予包訪問權(quán)限,包內(nèi)的其他類可以訪問該成員;
3).繼承而來的類既可以訪問public成員也可以訪問protected成員。
4).提供訪問器和變異器方法,以讀取和改變數(shù)值。
1.包訪問權(quán)限
默認訪問權(quán)限沒有任何關(guān)鍵字,但通過是指包訪問權(quán)限,這表示當前報中的所有其他類都對那個成員有訪問權(quán)限,但是對于這個包之外的所有類,這個成員確是private。
包訪問權(quán)限將包內(nèi)所有相關(guān)的類組合起來,以使它們彼此之間可以輕松地相互作用。
注意:如果兩個類處于相同的目錄下,并且沒有給自己設(shè)定任何包名稱,Java會將這樣的文件自動看作是隸屬于該目錄的默認包之中,于是這些文件互相之間有包訪問權(quán)限。
下面的例子說明了這個問題:
//類Cake和Pie處于同一目錄下,沒有明確的顯示在任何包中 class Pie{ void f(){ System.out.println("Pie.f()"); } } class Cake{ public static void main(String[] args){ Pie x = new Pie(); x.f(); } } //輸出為Pie.f()
2.public:接口訪問權(quán)限
使用關(guān)鍵字public,就意味著其后的成員聲明對所有人可用,特別是使用類庫的客戶程序員也是如此。
3.private:你無法訪問
關(guān)鍵字private表示出了包含該成員的類之外,其他任何類都無法訪問這個成員。同一包內(nèi)的其他類不可以訪問這個類的private成員,因此這相當于自己隔離了自己。
private關(guān)鍵字的這種作用有許多用途,比如,控制如何創(chuàng)建對象,阻止別人直接訪問某個特定的構(gòu)造器(或全部構(gòu)造器)???/p>
下面的例子:
class Sundae{ private Sundae(){} static Sundae makeASundae(){ return new Sundae(); } } public class IceCream { public static void main(String[] args){ Sundae x = Sundae.makeASundae(); } }
這個例子里,我們可以通過調(diào)用makeASundae()方法來創(chuàng)建Sundae對象,但是不能通過構(gòu)造器來創(chuàng)建。
這對于類中的private域同樣適用。
但是要注意一點,不能因為在類中某個對象的引用是private,就認為其他的對象無法擁有該對象的public引用。
4.protected:繼承訪問權(quán)限
如果創(chuàng)建了一個新包,并自另一個包繼承類,那么唯一可以訪問的成員就是源包的public成員。
有時,基類的創(chuàng)建者希望將某個特定成員的訪問權(quán)限賦予派生類而非所有類,這就需要使用關(guān)鍵字protected來實現(xiàn)。
注意,protected也提供包訪問權(quán)限,即相同包內(nèi)的其他類也可以訪問此類的protected元素。
二、接口和實現(xiàn)
訪問權(quán)限的控制通常被稱為具體實現(xiàn)的隱藏。
把數(shù)據(jù)和方法包裝進類中,以及具體實現(xiàn)的隱藏,常共同被稱作是封裝。
出于兩個重要的原因,訪問權(quán)限控制將權(quán)限的邊界劃在了數(shù)據(jù)類型的內(nèi)部:
1.要設(shè)定客戶端程序員可以使用和不可以使用的界限。可以在結(jié)構(gòu)中建立自己的內(nèi)部機制,兒不必擔心客戶端程序員會偶然地將內(nèi)部機制當做是他們使用的接口的一部分。
2.接口和具體實現(xiàn)進行分離。
三、類的訪問權(quán)限
Java中,訪問權(quán)限修飾詞也可以用于確定庫中的哪些類對于該庫的使用者是可用的。
修飾詞必須放在關(guān)鍵字class之前。例如:
public class Widget{......}
或
improt access.Widget;
要知道,類不可以是private的(如果類是private的,那么除了該類之外,其他任何類都不可以訪問它),也不可以是protected的(其實一個內(nèi)部類可以是private或protected的,但這是特例,后續(xù)文章中敘述),只可以是包訪問權(quán)限或public的。
如果不希望其他人訪問該類,可以把該類的所有構(gòu)造器都指定為private,阻止任何人創(chuàng)建該類的對象。但這也有例外,這種做法不能阻止你在該類的static成員內(nèi)部創(chuàng)建該類。我們來看下邊的例子:
class Soup1{ private Soup1(){} public static Soup1 makeSoup(){ //使用靜態(tài)方法創(chuàng)建對象 return new Soup1(); } } class Soup2{ private Soup2(){} private static Soup2 ps1 = new Soup2(); //使用單例模式創(chuàng)建對象 public static Soup2 access(){ return ps1; } public void f(){} } public class Lunch { void testPrivate(){ //Soup1 soup = new Soup1; 不能執(zhí)行 } void testSingleton(){ Soup2.access().f(); } }
我們可以看到,Soup1和Soup2類的構(gòu)造器都是private的,誰也無法直接使用構(gòu)造器來創(chuàng)建該類的對象了。但是我們也可以使用這兩個類:在Soup1中創(chuàng)建一個static方法,在這個方法中使用構(gòu)造函數(shù)創(chuàng)建一個Soup1對象并返回它的引用;Soup2的創(chuàng)建用了設(shè)計模式中的單例模式,只能創(chuàng)建它的一個對象。Soup2類的對象是作為Soup2的一個static private成員而創(chuàng)建的,所以有且僅有一個,而且除非是通過public方法access(),否則是無法訪問到它的。
此外,一些限制也值得注意:
1.每個編譯單元都只能有一個public類。
2.public類的名稱必須完全與含有給編譯單元的文件名相匹配,包括大小寫。
3.如果編譯單元內(nèi)沒有帶public的類,這時可以對文件隨意命名。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Java中成員方法與成員變量訪問權(quán)限詳解
- 舉例詳解Java中的訪問權(quán)限修飾符
- 詳細學習Java Cookie技術(shù)(用戶登錄、瀏覽、訪問權(quán)限)
- java類訪問權(quán)限與成員訪問權(quán)限解析
- Java編程訪問權(quán)限的控制代碼詳解
- 理解Java訪問權(quán)限控制
- Java中四種訪問權(quán)限資料整理
- 解決Java提示正在嘗試分配更低的訪問權(quán)限問題
- Java訪問權(quán)限控制的重要性深入講解
- 淺析java修飾符訪問權(quán)限(動力節(jié)點Java學院整理)
- java四種訪問權(quán)限實例分析
- Java訪問權(quán)限原理與用法詳解
相關(guān)文章
Mybatis中TypeAliasRegistry的作用及使用方法
Mybatis中的TypeAliasRegistry是一個類型別名注冊表,它的作用是為Java類型建立別名,使得在Mybatis配置文件中可以使用別名來代替完整的Java類型名。使用TypeAliasRegistry可以簡化Mybatis配置文件的編寫,提高配置文件的可讀性和可維護性2023-05-05關(guān)于java.math.BigDecimal比較大小問題
這篇文章主要介紹了關(guān)于java.math.BigDecimal比較大小問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析
這篇文章主要介紹了Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08SpringCloud @RefreshScope注解源碼層面深入分析
@RefreshScope注解能幫助我們做局部的參數(shù)刷新,但侵入性較強,需要開發(fā)階段提前預知可能的刷新點,并且該注解底層是依賴于cglib進行代理的,所以不要掉入cglib的坑,出現(xiàn)刷了也不更新情況2023-04-04