Java 控制访问权限
一个类库开发者(开发对外提供的接口)需要修改和不断完善自己的代码,以使其更可读、更易理解并更可维护,但之前的消费者却希望你的代码在某些方面保持不变,要不然他们的代码将不能正常工作,如果你不清楚哪些接口被调用过,那么你便会束手束脚,无法对任何事物做改动。
这里便引出了一个问题:如何把变动的事物和保持不变的的事物区分出来?Java提供了访问权限修饰词来解决此问题,使用权限修饰词可以告知客户端程序员哪些接口和方法是可用的,哪些是不可用的。
访问权限修饰词
包访问权限
如果没有指定任何权限修饰词,则默认为“包访问权限”,也就意味着当前包中(package)所有其他类对那个成员都有访问权限,包之外的所有类则无权访问。
类控制哪些代码有权访问自己的成员,取得对某成员访问权限的途径有:
- 使该成员成为public
- 不加访问权限修饰词,并将调用类与其置于同一包内
- 继承该类以获得对该类public成员和protected成员的访问权
- 提供访问器(accessor)和 get/set方法以读取和改变其值(后面会举例)
private权限
关键词private表示除了包含该成员的类内部以外,其它任何类都无法访问。于是我们将给客户端程序员使用的成员标记为public以外其余都声明为private,但其实private的作用主要并不是这个,因为即使不使用private修饰,成员的默认的包访问权限对于客户端程序员来说也是不可访问的(客户端和类包一般不会位于同一个包下)。
private的一个重要用途是在多线程环境下,可以控制用户如何创建对象,通过阻止别人访问某个特定的构造器。示例如下:
public class IceCream {
public static void main(String[] args) {
Sundae sundae = Sundae.makeASundae();
// Sundae sundae = new Sundae(); //这里不可访问,会报错
Sundae2.access().f();
}
}
class Sundae{
private Sundae() {} //构造函数限制为private
static Sundae makeASundae(){
return new Sundae();
}
}
//Sundae2使用了单例(singleton)单例模式,因为你始终只能创建一个Sundae2对象
class Sundae2{
private Sundae2() {} //构造函数限制为private
private static Sundae2 sundae2 = new Sundae2();
public static Sundae2 access() {
return sundae2;
}
public void f() {}
}
protected继承访问权限
在一个包中继承了另一个包的某类,那么唯一可以访问的是基类的public成员,但如果基类的创建者希望某个特定成员的访问权限可以赋予派生类而不是所有类,这时便需要protected来完成这一工作,其实protected就是用来处理继承中的权限控制问题。
类的访问权限
注意类不可以是private的也不可以是protected的,对于类的访问权限只有两个选择:包访问权限(没有修饰符)或public访问权限。在eclipse中如果试图使用private或protected去修饰一个类时会提示:
Illegal modifier for the class IceCream; only public, abstract & final are permitted