Chapter6 访问控制(Access Control)
1. Package: library单元
-
Java提供了多种权限控制关键字(access keyword):public, protected, package access(no keyword), private权限依次降低。Package access即默认权限(可以把package理解为一个文件夹),如果类名或method等无前缀时,即表示只有当前package中的部分可以访问。如果把package看成是一个library单元的话,那么这个单元里面可以包括多个class。以java.util为例,这是java的一个package名称,而ArrayList是这个package中的一个class。在调用时我们可以直接调用完整的class名(包括package名)。
示例如下:
public class PackageTest1 { public static void main(String[] argv){ java.util.ArrayList a = new java.util.ArrayList(); } }
可以看到此时并不需要import。当然,也可以采用import的形式,如import java.util.ArrayList或者import packagename.*,表示把该package下的class都添加进来。
1.1 代码组成
- 我们在用java进行编程时,会保存一个后缀为.java的源文件。java编译器会把这个.java文件看成一个编译单元,在这个编译单元中可以有多个class声明,但只能有一个(可以没有)是public类型的,且这个public的类名必须和文件名相同。编译之后会根据这个.java文件的类生成多个.class文件,多个.class文件也可以压缩成一个.jar文件(java archive)
1.2 创建唯一的package名
- 想象一下,如果我们把所有的.java文件放在同一个文件夹中,那么就不允许重名,这在程序代码量较大或者多人共同开发的情况下,维护性和扩展性将会变得极差。于是对java文件进行归类就显得十分自然,而这跟文件系统又有几分相似。因此java的package也就是对应os中的文件,这使得定位java文件变得非常容易。而且我们可以把需要放在一起的文件放在同一个package目录下,如之前提到过的java.util。java为了让不同用户之间能够互相独立,采用取反的域名加上类地址的方式使得外部程序可以导入指定library,因为每个用户的域名都是独一无二的。比如我的域名是 www.pppeter. org,创建的Test类在thinkingjava文件目录下,那么org.pppeter.www.thinkingjava.Test.class就可以作为我的library地址被其它程序import。
1.3 命名冲突
- 之前提到过,我们可以通过 * import一整个package下的所有.class文件,但这时候可能会出现一个问题:也许不同package中存在相同的class名。比如java.util中一个类名是ArrayList,而import的另一个package中也有一个叫做ArrayList的类。当然如果我的程序中并没有用到这个名字冲突的类那么完全没有问题,但当我需要使用时,就会报错。解决方法是我可以具体指定类名,如之前的java.util.ArrayList,或者尽量在import时尽可能不要使用*,当然这视具体情况而定。
1.4 自定义library
-
我们可以自己定义一个library来简化System.out.print这个比较长的输出。当别的程序需要使用这个library时,同样需要import自定义的library。这里采用的import static XXX.*的形式表示导入XXX类中所有静态方法。
示例如下:
public class Print {