访问权限控制
等级权限(降序):public, protected, 包访问权限(无关键字),private。
1. 包:库单元
1.1 代码组织
- java源文件(.java),又称编译单元(转译单元)
- 输出文件,后缀名(.class),java解释器负责这些文件的查找、装载和解释。
1.2 创建独一无二的包名
package语句必须是文件第一行非注释的程序代码。
java解释器的运行过程:
- 找到环境变量CLASSPATH,包含一个或多个目录,用作查找.class文件的根目录。
- 从根目录开始,解释器获取包名并把每个点替换成反斜杠,已从CLASSPATH的根中产生一个路径名称。
- 得到的路径会与CLASSPATH中的各个不同项连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。
2. Java访问权限修饰词
2.1 包访问权限
如果不提供任何访问权限修饰词,默认它是“包访问权限”。
注: 其它包内的类要取得对某成员的访问权唯一途径
- 使该成员成为public.
- 不加访问权限修饰器并将其他类放置同一个包内.
- 继承,可以访问public和protected成员。只有两个类在同一个包才可以访问包权限的成员。
- 提供访问器(accessor)和变异器(mutatos)方法(即Get/Set方法)。
2.2 public:接口访问权限
公共成员,完全公开,没有访问限制。
2.3 private : 私有成员
如果令类的构造器为private, 则不能通过构造器创建对象。若唯一的构造器被私有,则阻碍对此类的继承。
2.4 protected : 继承访问权限
只有继承他的类才可以访问他的方法。被其修饰的属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以问。
权限 | 类内 | 包内 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
默认 | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
注: 封装指将数据和方法包装进类里,以及具体实现的隐藏(也称就是 访问权限的控制)。
3. 接口和实现
访问权限控制将权限的边界划在数据类型的内部,两个原因:
-
设定客户端程序员可以使用和不可以使用的界限。说白了就是使用户不要触碰那些他们不该触碰的部分,只提供给他们能实现的功能,而非实现细节。
-
将接口和具体实现进行分离。
类库设计者设计一个功能模块,在底层进行实现,而只对客户端程序员暴露出接口,客户端程序员通过调用该接口即可使用该功能。
严格将接口和实现进行分离后,类库设计者就可以随意更改类的内部工作方式(出于某种目的,比如提高效率),而不影响客户端程序员的使用,实现方式改变,但接口不变。
4. 类的访问权限
限制:
-
- 每个编译单元(文件)都只能有一个public类。即表示每个编译单元都有单一的公共接口,用public来表现。
-
- public类的名称必须完全与含有该编译单元的文件名称名一致(包括大小写)。
-
- 不常用:编译单元可以不写public类,此时文件名任意。
注意: 类不可以是private的(这样会使除该类以外,其他任何类都不可以访问),也不可以是protected。所以对于类仅有两个选择:包访问权限和public。
例外:可以在该类的static成员内部创建对象
//创建一个新的Soup1对象并返回一个对它的引用
class Soup1(){
private Soup1(){}
public static Soup1 makeSoup(){
return new Soup1();
}
}
//单例设计模式,只能创建一个对象
class Soup2(){
private Soup2(){}
private static Soup2 p1 = new Soup2();
public static Soup2 access(){
return p1;
}
}