为什么要设置访问权限:
访问控制(或者隐藏具体实现)与"最初的实现并不恰当"有关。当程序员发现有更好的方式去实现相同的功能时,代码则需要重构。但是在修改和完善代码中,通常客户端程序员希望在某些部分保持不变。这种你变他不变的矛盾就随之产生了。解决该矛盾关键在于如何将变动的事物和保持不变的事物区分开来。
在叙述具体的解决方式之前,应先谈谈类库和包。类库是包的集合,正如库房之中有很多个包裹。
包:
包是库的单元。包内含有一组类,他们在唯一可确定的名字空间下组织在一起。包名第一部分是类的创建者的反顺序的Internet域名,这是包名唯一的关键;包名的第二个部分对应机器上的一个目录,通过这个目录,可以确定.class文件所处的位置。
若不使用关键字import导入某个名字空间下(包)的类,代码将会显得特别冗长。如:
java.util.ArrayList list = new java.util.ArrayList();//没有使用import java.util.ArrayList时
ArrayList list = new ArrayList();//使用之后
一个比较隐藏的问题,当使用*号导入某个包下所有的类时,你自己又创建了一个相同名字的类,在创建该类的对象时将会引起冲突,这时需要明确的指出是调用哪个包下的类。本质是让编译器知道在哪个文件目录下寻找,因为包名第二部分就对应着目录。
定制自己的工具库:
创建自己的工具库可以减少和消除重复的程序代码。比如书中简化的System.out.println()的写法等,都是通过自己重写该输出方法实现的。
当拥有自己的域名并发布代码后,别人就可以import你的类库并使用。
对于一个域(数据成员)或者一个方法:
每个访问权限修饰词仅控制它所修饰的特定定义的访问权。如果不添加任何访问修饰词,则默认是包访问权。因此,所有的域或者方法都有其权限访问控制。
1)包访问权限:
当前包中所有其他的类都可以对该成员进行访问。但对于这个包之外的所有类,这个成员的访问权限则是private。
2)public接口访问权限:
使用关键字public,就意味着public后面紧跟的成员是对外共享的。注意:对于两个处于同一个目录下的文件,它们即使都没有任何访问权限修饰词,没有指定包,但是却可以互相调用。实际上是因为Java将这样的文件自动看作是隶属于该目录的默认包中,这个默认包我们是看不到的,于是为该目录中所有的文件都赋予了这个包访问权限。
3)private你无法访问:
private表示出了包含这个成员的类之外,其他任何类都无法访问这个成员。任何可以肯定是一个类的辅助方法时,都可以指定为private,以确保不会再其他地方误用到他。此外,private还可以控制对象的创建,只需在类的构造器前面加上private,并添加创建对象的方法,则其他任何地方都不能直接创建该类的对象,必须通过调用创建对象的方法才可以实现。
class Sundae{
private Sundae(){}//控制对象的创建
static Sundae makeSundae(){
return new Sundae();
}
}
public class Test{
public static void main(String[] args){
Sundae x = Sundae.makeSundae();
}
}
4)protected继承访问权限:
同时具有包访问权限和派生类使用权限。
类的访问权限:
1)每个编译单元都只能有一个public类,但是域或者方法可以有多个。
2)public类的名称必须和文件名一致,否则报错。
3)虽然不是很常用,但是完全不带public也是可能的。在这种情况下,是可以对文件随意命名。
注意,类既不可以是private的,也不可以是protect的(事实上,内部类是可以的)。所以对于类的访问权限,只有两个选择,包访问权限和public。如果不希望其他任何人对该类拥有访问权限,可以把该类所有的构造器都指定为private,从而阻止任何人直接创建该类的对象,除非在这个类中有一个static方法用以创建这个类的对象,然后其他类通过调用该方法获取。书中还讲述了如何应用设计模式的思想,控制每次创建对象有且仅有一个。