J2SE理解之一:声明和访问控制
Java的聲明和訪問控制
????????????????????張磊zhangleispirit@gmail.com
Java的聲明元素主要包括類(包括抽象類),接口,數組,異常和枚舉類型的聲明。其中各個部分又包含如下的各種基本元素:
????類(包括抽象類):屬性聲明,構造方法聲明,方法聲明,變量(注:這里的變量不包含屬性)
接口:接口常量和接口方法
數組,異常,枚舉。
類的聲明:
1.類本身的聲明:
?????對類的聲明來說,主要包括類的訪問權限聲明和非訪問修飾符的使用。對于一個普通的Java類(POJO)來說,主要的訪問權限修飾符只有兩個public和默認權限,內部類可以有private權限。非訪問修飾符主要包括abstract,final和strictfp.
?????(1)這里先討論非訪問修飾符,下面是基本的規則:
?????abstract:聲明一個類是抽象的。
?????final:聲明一個類是可以被繼承的。
?????strictfp:聲明一個類中所有的方法在處理浮點數時遵循IEEE754規則。
?????由上面的這些規則可以得出一個結論:一個類不可能既聲明為abstract的,又聲明為final的。
?????
?????抽象類的實質即為繼承它的類定義了一組行為準則,任何繼承它的類都必須實現抽象類所定義的抽象方法,抽象類不可以實例化,抽象類中可以不包含抽象方法,但是含有抽象方法的類一定要聲明為抽象類。
?????final類表示一個類似不能被繼承的。如果你不希望一個類的行為被改變,或者說該類的行為是整個系統的基礎,就跟數學中的數字一樣的話,就可以把這個類聲明為final的。
?????(2)類的訪問權限修飾符:
????????首先需要弄清楚的是類的訪問包括哪些方面:
????????????一個類中創建另一個類的實例;
????????????一個類繼承自另一個類;
????????????一個類中的方法訪問另一個類的方法和變量。?
????????
????????類的訪問權限聲明為public的,表示該類可以被任意的類訪問,當然,在其他類中訪問該類時,還是要在源文件的頭部做相應的import工作。
???????
????????類的訪問權限為默認權限,則表示和該類處在同一個包下的類可以訪問它?,此處注意以下比較容易忽視的地方:
???????源文件一:
????????package??cert;
????????class?test1?{}
???????源文件二:
????????package??cert2;
????????import?cert.test1;
????????public?class?test2?extends?test1{}
?????這里test2類會產生錯誤,因為test1是默認訪問權限,test2?使用繼承的方式訪問test1,由于這兩個類不在同一個包中,因此test2是無法看到test1?的。
?????2.類的成員訪問權限聲明
??????(1)訪問權限的聲明:
???????類的成員可以使用全部的四種訪問權限:public?,protected,默認,private。
???????
???????這里需要記住的第一條準則就是:判斷類的成員的訪問權限,必須先判斷類的訪問權限,如果整個類對于另一類來說都是不可見的,那么這個類的所有成員都是不可見的。
???????類的成員的訪問權限,當涉及到子類時會變得很復雜,這里首先要弄清楚兩種訪問的區別:
??????一個類的方法的代碼是否能夠訪問另一個類的成員(即:通過在一個類中創建另一個類的對象,通過該對象來實現對另一個類的訪問)。
??????一個類是否能夠繼承超類的成員。
??????public成員訪問:
??????如果一個類的成員聲明為public,那么通過創建類的實例的方式,都是可以訪問的,只要類的訪問權限沒有問題。通過繼承,子類可以擁有超類的public成員,而且,第三個類訪問該子類時,仍然可以訪問子類所繼承的超類的成員。
??????舉例說明如下:(注:三個類位于不同的源文件中)
???????package?cert;
???????public?class?Test1?{
????????public?String?doThing(){
??????????????return?"zhanglei?";
}
}
??????package?cert2;
??????import?cert.Test1;
??????class?Test2?extends?Test1{
public?String?doThing2(){
????return??"hello,"+doThing();
}
??????}
?????
??????package?cert2;
??????import?cert2.Test2;
??????public?class?Test3{
?????????public?static?void?main(String[]?args){
Test2?test=new?Test2();
System.out.println(test.doThing2());
}
??????}
private?成員訪問:
???????表示該成員是該類的私有成員,任何類通過上面的兩種方式都是不可訪問的。只可以在該類的定義中使用,或者通過該類的get和set方法來訪問。
???這里插一點:一個類的構造函數是可以被聲明為私有的,一旦該類的構造方法被聲明為私有的,則必須提供一個public的方法來創建該類的實例,主要用在工廠模式和單態模式中。
???另外一個需要注意的地方是:對于超類的私有方法,若在子類中出現了相同簽名的方法,這不是重寫。而只是剛好超類和子類的兩個方法相同。其理論依據就是:子類是不能繼承超類的私有方法的。
默認成員訪問:
???表示該類的成員在同一個包下的其他類中是可以通過上面兩種方式來訪問的。
protected成員訪問:
???這個訪問權限是最麻煩的,分成兩種情況來討論:
???1.當考慮一個類通過創建另一個類的實例的方式實現訪問時,它產生的行為與默認權限相同,既在同一個包中的類可以相互創建實例訪問。這里有一種特殊情況:就是當一個類是另一個類的子類時,如果兩個類不在同一個包中,那么子類通過創建超類的實例的方式是不可以訪問的,就和兩個基本類的行為一樣,這里不要受繼承關系的影響。
???2.當考慮一個類繼承另一個類的成員時,當超類的成員聲明為protected?的,則包內和包外的繼承自它的子類都可以擁有該成員,而且對于子類來說,它通過繼承擁有的成員對它來說是私有的,任何第三方的類都是不可訪問的。
3類的成員非訪問權限的聲明:
??????final:final類是防止有類繼承該類。final方法是防止該方法在子類中被重寫。另外final???關鍵字可以被用在方法的參數,表示該參數是只讀的:
??????????public?String?getThing(int?number1,final?number2){}??
?abstract:聲明一個抽象方法,方法以分號結束,沒有大括號。
?????public?String?setSomething();???//抽象方法
?????public?String?setSomething(){?}??//實例方法
?????abstract抽象方法不能被聲明為private的,因為抽象方法始終需要被重寫。
?????abstract抽象方法不能和static同用。
synchronized:只能用于方法聲明,表示方法一次只能被一個線程訪問。
native:只能用于方法聲明,表示該方法是用其他的語言來實現的,native的方法體必須是以;分號結束,沒有方法體。
具有可變參數列表的方法:
??舉例:void?doStuff(int...?x){}
????????void?doStuff(String?str,Animal...?animal){}
規則是這樣的:1.參數類型后面接省略號(...),一個空格,以及保存接收參數的數組名稱
??????????????????2.可變參數必須是最后一個參數,且方法中只能有一個可變參數。
接口的聲明:
?????1.接口聲明:與類本身的聲明相同,接口隱含是abstract的,因此不能聲明為final的。另外需要注意接口之間是可以多繼承的,使用extends關鍵字。
?????2.接口方法的聲明:接口的方法,隱含都是public和abstract的,因此接口方法不能聲明為final,static,private和protected的。
?????注意:接口和抽象類的方法聲明,其子類在實現這個方法時,不能修改方法聲明的訪問權限。
?????
?????3.接口常量的聲明:接口內允許放置常量,因此隱含public?static?final的,實現接口的類不能修改接口中定義的常量的值。
數組的聲明:
?????數組有兩種聲明方式:
?????int[]?key;或者
?????int?key[];
?????多維數組:
?????String[][]?str;或者
?????String?str[][];或者
?????String[]?str[];
?????注意:數組聲明中,不能包含數組的長度。?
枚舉的聲明和定義:
????1枚舉的聲明:
??????枚舉的聲明位置有兩種:一種是單獨成類。另一種是放在類中,但是不能放在類的方法中。枚舉的訪問修飾只能使用public和默認。
??????枚舉不能被聲明為static,final?,abstract.
舉例:
????第一種方式:enum?Test{SMALL,MIDDLE,BIG};
第二種方式:public?class?Test2{
?????????????enum?Test{SMALL,MIDDLE,BIG};
?????????????Test?test;
?????????????public?static?void?main(String[]?args){
???????????????Test2?test2=new?Test2();
test2.test=Test.BIG;
}
}
????
2枚舉的實質及分析:枚舉的實質就是一個類,拿Test枚舉來說,可以這樣類比:Test是一個類,它的成員是三個Test類型的對象SMALL,MIDDLE,BIG.
?枚舉可以定義構造函數和方法(因為枚舉還是一個類)
?例如:
enum?Test{
???SMALL(1),MIDDLE(2),BIG(3);//這里用整數值初始化了三個對象,隱式調用了構造函數
???Test(int?num){
???????this.num=num;
??}//這里定義了構造函數
???private?int?num;//枚舉類的核心參數,可以做任意修改
???public?int?getNum(){
?????return?num;
}
}
注:枚舉類型的構造函數是可以重載的。
轉載于:https://www.cnblogs.com/zhangleispirit/archive/2008/10/13/1309874.html
總結
以上是生活随笔為你收集整理的J2SE理解之一:声明和访问控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Delphi写扬声器音乐
- 下一篇: ArcGIS.Server.9.2.Do