1. 为什么需要权限修饰符
权限修饰符是为了满足封装的需要,面向对象编程一大特性就是封装,封装不仅要做到隐藏类的属性和函数,也要做到暴露一些属性和函数给外界调用。为了满足这个需求,就产生了权限修饰符
2. 权限修饰符可见性范围
权限修饰符 | 同一个类 | 同一个包 | 不同包的子类 | 不同包的非子类 |
---|---|---|---|---|
Private | √ | |||
Default | √ | √ | ||
Protected | √ | √ | √ | |
Public | √ | √ | √ | √ |
3. Protected关键词详解
其他三个修饰符还比较好理解,protected在理解上需要牢记两条准则:
- 父类的protected成员是包内可见的,并且对子类可见;
- 若子类与父类不在同一包中,那么在子类中,子类实例可以访问其从父类继承而来的protected方法,而不能访问父类实例的protected方法。
在碰到涉及protected成员的调用时,首先要确定出该protected成员来自何方,其可见性范围是什么,然后就可以判断出当前用法是否可行了
下面给出几个示例:
package p1;
public class Father1 {
protected void f() {} // 父类Father1中的protected方法
}
package p1;
public class Son1 extends Father1 {}
package p2;
public class Son11 extends Father1{}
package p1;
public class Test1 {
public static void main(String[] args) {
Son1 son1 = new Son1();
son1.f(); // Compile OK ----(1)
son1.clone(); // Compile Error ----(2)
Test1 test1 = new Test1();
test1.clone(); // Compile OK ----(3)
}
}
(1):son1的f方法来自于父类Father1,f方法的可见范围是p1包和它的两个子类son1和son11. 因此编译通过
(2):son1的clone方法来自于java.lang包的Object,clone方法的可见性范围是java.lang包和它的所有子类,但不可以在Test1中使用son1的clone方法。而(3)就满足可见性范围
package p1;
class MyObject1 extends Test1 {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package p2;
public class Test1 {
public static void main(String args[]) {
MyObject1 obj = new MyObject1();
obj.clone(); // Compile Error -----(1)
}
}
obj的clone方法是obj自己重写的,因此它的可见性范围是p1包和MyObject1的子类,当然就不能在父类中使用了
package p1;
class Test{
public static void main(String[] args) throws CloneNotSupportedException {
new Test().clone(); // Compile OK ----(1)
Object o = new Object();
o.clone(); // Compile Error ---(2)
}
}
(1): Test对象的clone方法是父类Object的,可见性范围是java.lang包和Test类,编译通过
(2): 如果父类和子类不在同一个包,父类对象实例的方法不可以在子类中被父类的对象调用,这算一个规则吧。
警示:个人的水平有限,文中难免有错漏之处,如果有读者发现了,希望可以提出来,大家一起交流,共同进步