Java访问控制修饰符之protected
protected可见性说明
- 基类的 protected 成员是包内可见的,并且对子类可见;
- 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。
针对protected修饰符的这两个特点,下面进行举例说明。
注1:例中用到的clone()函数是java.lang包中Object类内的函数,其访问控制修饰符为protected,当创建一个类时,默认继承java.lang.Object类。
注2:默认创建类A时已进行一次继承,继承自Object类,基于A创建的子类为Object类的孙类。
举例说明
package p1;
public class Father1 {
public static void main(String[] args){
Son11 son11 = new Son11;
son11.clone(); //情况1
Son1 son1 = new Son1;
son1.clone(); //情况2
}
}
package p1;
public class Son1 extends Father1 {
public static void main(String[] args){
Son11 son111 = new Son11;
son111.clone(); //情况3
Father1 father11 = new Father1;
father11.clone(); //情况4
}
}
package p11;
public class Son11 extends Father1{
public static void main(String[] args){
Son1 son2 = new Son1;
son2.clone(); //情况5
Father1 father2 = new Father1;
father2.clone(); //情况6
}
package p1;
public class Test1 {
public static void main(String[] args) {
Son1 son3 = new Son1();
son3.clone(); //情况7
Son11 son33 = new Son11();
son33.clone(); //情况8
Father1 father3 = new Father3();
father3.clone(); //情况9
Test1 test1 = new Test1();
test1.clone(); //情况10
}
}
- Father1类(父类)中进行测试
-
情况1:编译通过。
clone()方法是Object类中的protected方法,其可见范围为Object类所在的包(java.lang包)和其子类(注意在涉及到孙类时,理清其不同分支)。对于情况1而言,Son11的clone()方法直接继承自Father1类,间接继承自Object类,所以实例son11的clone()方法可见范围为java.lang包,Father1类和Son11类。虽然Son11和Father1不在一个包,但不受影响。 -
情况2:编译通过。
对于情况2,和情况1基本相同,只是Son1和Father1在同一个包中,所以仍能编译通过。
- Son1类(子类1)和Son11(子类2)中进行测试
-
情况3:编译不通过。
如情况1所说,son11的clone()方法可见范围为java.lang包,Father1类和Son11类。而Son1类不在这一范围内,所以编译步通过。 -
情况4:编译不通过。
对情况4,Father类clone()方法继承自Object类,所以其可见范围为java.lang包和Father1类。同时,针对原则:子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。在情况4中使用的访问方法是访问基类实例的protected方法,所以会访问失败。 -
情况5:编译不通过。
与情况3类似。 -
情况6:编译步通过。
与情况4类似。
- 在Test1类(和父类同包)中测试
-
情况7-9:编译不成功。
根据以上分析,Test1不在其可见范围中,所以编译不成功。 -
情况10:编译成功。
在这种情况中,因为Test1类继承自Object类,所以可以成功访问clone()方法。
在上述情况的情况4中,提到了一个原则,即:
若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。
情况4之所以访问不成功,是因为其对应了访问基类实例的protected方法这一做法。
访问其从基类继承而来的protected方法,指的是子类继承了父类(包括父类的方法),在实例化时,对子类进行实例化,该实例可以调用父类的方法。
注意:如果将clone()方法重写,则继承的是重写后的方法。