当我们提到封装的时候,首先会想到属性的封装,这时就第一次接触了访问权限修饰词的概念。一般在构建一个类时,选择将属性私有化,方法公开化,这样的做法可以给我们带来很多好处,一是避免了使用该类时,直接访问成员属性带来的数据不安全;其次是,当我们处于团队协作的情况下,维护常常是一件需要很多开销的事,而在维护时,这种写法可以使你省去很多苦恼,因为不必担心修改的某个变量被其他类使用了,只需要考虑:所有对外公开的成员都功能一致。从这个小例子就可以看出来访问权限修饰词的重要性,而在这里边还有一些不易理解的点,这里就对这四个修饰词来一一试验。
首先我们讨论访问修饰词修饰类。我们都知道,类只能声明为public或者默认权限,当声明为默认权限时,代表对包外任何类都不可见;当声明为public时,在任何位置可见,且该类所在的java文件必须与该类同名。一个java文件可以有多个类,但是只能有一个public类。
其次我们讨论访问修饰权限修饰词修饰成员变量,成员范围时的情况。我们在学习的时候,经常地会看到下面这张图:
类内 | 类所在的包内 | 包外子类内 | 所有类 | |
public | 可以 | 可以 | 可以 | 可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
default(默认) | 可以 | 可以 | 不可以 | 不可以 |
private | 可以 | 不可以 | 不可以 | 不可以 |
- 当修饰词是private时,只有类内能够访问到,其他任何类都不能直接访问到。
- 当修饰词是default时,包内能以任何形式访问到,包外任何形式都不能访问到,所以默认又称为“包访问权限”。
- 当修饰词是public时,任何类内都能访问到。
上面三条中的“直接访问”指代的是:由直接点的方式去访问,例如:Student.name。以上三条都很好理解,因为泾渭分明,私有时只有类内可以,包访问权限时只有包内可以,公开时所有的类都可以访问到,那么我们再来讨论比较不好理解的protected。首先看下面的代码:
package practiceoop;
public class Aoo {
protected int i = 5;
}
package thingking;
import practiceoop.Aoo;
class Boo extends Aoo{
public void visit(){
System.out.println(this.i); //第一种,通过this访问
System.out.println(super.i); //第二种,通过super访问
Aoo o1 = new Aoo();
System.out.println(o1.i); //第三种,通过new一个父类对象访问
Boo o2 = new Boo();
System.out.println(o2.i); //第四种,通过new一个自己的对象来访问
Coo o3 = new Coo();
System.out.println(o3.i); //第五种,通过new一个父类其他子类的对象来访问
}
}
class Coo extends Aoo{
}
首先观察上述的代码可以看到:Aoo处于practiceoop这个包中,Boo和Coo处于thinking这个包中,Boo和Coo都是Aoo的子类,那么我们执行上面的代码,会发生什么呢?
执行后的结果是这样的:第三种和第五种都会报错,提示The field Aoo.i is not visible,即变量i不可见。
从上述结果我们看出来,并不是说在子类内就一定能访问到protected变量的,可以推出一个简单的推论:只有在子类内的该子类对象可以访问到,这样,protected修饰词也很好理解了:
包内可以任何形式访问到,包外除子类外不能以直接形式访问到,包外子类内,只有该子类的对象可以直接访问到。