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无修饰符,故只有包访问权限,在同一个包中才能正常使用。