Thinking in java 第6章 訪問權限控制
6.1 包:庫單元
1. 每個編譯單元(java源文件)只能有一個public類,否則編譯器就不會接受。
2. 在文件起始聲明package xxx;就表示該編譯單元是名爲xxx的類庫的一部分。
3. Java沒有C的條件編譯功能。C在絕大多數情況下用此來解決跨平臺問題。而Java自身可以自動跨越不同平臺,因此該功能對Java沒必要。
6.2 Java訪問權限修飾詞
public | 包之間也可以隨意訪問 |
protected | 繼承的子類可以訪問;包內可以隨意訪問 |
無 | 包內可以隨意訪問 |
private |
只有類內可以訪問 |
6.4 類的訪問權限
1. 如果不希望其他任何人對該類擁有訪問權限,可以把所有的構造器都指定爲private,從而阻止任何人創建該類的對象。但有一個例外,就是你在該類的static成員內部可以創建。
練習:
練習1:在某個包中創建一個類,在這個類所處的包的外部創建該類的一個實例。
package Chapter6;
import Chapter2.E2_1;
public class E1 {
public static void main(String[] args) {
E2_1 e = new E2_1();
}
}
練習2:將本節的代碼片段改寫爲完整的程序,並校驗實際所發生的的衝突。
Chapter2和Chapter3中都有Dog類,會提示Multiple choices...不能編譯。
package Chapter6;
import Chapter2.*;
import Chapter3.*;
public class E2 {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
練習3:創建兩個包:debug和debugoff,它們都包含一個相同類,該類有一個debug()方法。第一個版本顯示發送給控制檯的String參數,而第二個版本什麼也不做。用靜態import語句將該類導入到一個測試程序中,並示範條件編譯效果。
註釋第二個則輸出args的地址值,註釋第一個則什麼都不輸出。
package Chapter6.debug;
public class Debug {
public void debug(String[] s) {
System.out.println(s);
}
}
package Chapter6.OffDebug;
public class Debug {
public void debug(String[] s) {
System.out.println("");
}
}
package Chapter6;
import Chapter6.debug.*;
//import Chapter6.OffDebug.*;
public class E3 {
public static void main(String[] args) {
Debug bug = new Debug();
bug.debug(args);
}
}
練習4:展示protected方法具有包訪問權限,但不是public。
package Chapter6.debug;
public class Debug {
public void debug(String[] s) {
System.out.println(s);
}
protected void func() {
System.out.println("you can visit this protected function!");
}
}
package Chapter6.debug;
public class test {
public static void main(String[] args) {
Debug bug = new Debug();
bug.func();
}
}
/*
you can visit this protected function!
*/
練習5:創建一個帶有public,private,protected和包訪問權限域以及方法成員的類。創建該類的一個對象,看看在你試圖調用所有類成員時,會得到什麼類型的編譯信息。請注意,處於同一個目錄中的所有類都是默認包的一部分。
同上,private不能調用。略。
練習6:創建一個帶有protected數據的類。運用在第一個類中處理protected數據的方法在相同文件中創建第二個類。
意義不明。翻譯錯誤。略。
練習7:根據描述access和Widget的代碼片段創建類庫。在某個不屬於access類庫的類中創建一個Widget實例。
練習1換皮。略。
練習8:效仿示例Lunch.java的形式,創建一個名爲ConnectionManager的類,該類管理一個元素爲Connection對象的固定數組。客戶端程序員不能直接創建Connection對象,而只能通過ConnectionManager中的某個static方法來獲取它們。當ConectionManager之中不再有對象時,它會返回null引用。在main()中檢測這些類。
package Chapter6;
public class ConnectionManager {
private static int cnt = 3;
private static Connection[] connection = new Connection[]{Connection.built(), Connection.built(), Connection.built()};
public static Connection get() {
if(ConnectionManager.cnt > 0) {
return ConnectionManager.connection[--ConnectionManager.cnt];
}
else {
System.out.println("NULL!");
return null;
}
}
public static void main(String[] args) {
Connection connection1 = ConnectionManager.get();
Connection connection2 = ConnectionManager.get();
Connection connection3 = ConnectionManager.get();
Connection connection4 = ConnectionManager.get();
}
}
class Connection{
private Connection() {
System.out.println("Connection has benn built!");
}
public static Connection built() {
return new Connection();
}
}
/*
Connection has benn built!
Connection has benn built!
Connection has benn built!
NULL!
*/
練習9:在access/local目錄下編寫以下文件(假定access/local目錄在你的CLATHPATH中)....然後在access/local之外的另一個目錄中創建下列文件.... 解釋一下爲什麼編譯器會產生錯誤。如果將Foreign類置於access.local包之中的話,會有改變嗎?
PackagedClass無修飾符,故只有包訪問權限,在同一個包中才能正常使用。