Protected关键字的可见性在于两点
1.基类的Protected成员是包内可见,并且子类可见
2.若子类和基类不在同一包内,那么在子类中,子类实例可以访问从其从基类继承而来的Protected方法,而不能访问基类实例的Protected方法
实例一:
package p1;
public class Father1 {
protected void f() {} // 父类Father1中的protected方法
}
package p1;
public class Son1 extends Father1 {}
package p11;
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)
Son11 son = new Son11();
son11.f(); // Compile OK ----(3)
son11.clone(); // Compile Error ----(4)
}
}
① 对于方法f()-Test1和Father1处于同一个包内,利用可见性的第一条可以验证
② 对于方法clone()来自于Father1-包java.lang内可见+Father1的两个子类可见,所以Test1不符合两条中的任意一条,编译错误
实例二:
package p2;
class MyObject2 {
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package p22;
public class Test2 extends MyObject2 {
public static void main(String args[]) {
MyObject2 obj = new MyObject2();
obj.clone(); // Compile Error ----(1)
Test2 tobj = new Test2();
tobj.clone(); // Complie OK ----(2)
}
}
① 对于方法clone(),是来自于MyObject2中,虽然复合可见性第一条,但是不符合可见性第二条-不同包的话不能访问基类实例中的Protected方法
② 相比与①,符合可见性第二条-不同包的话可以访问子类中继承基类的Protected方法
注:前两个实例是分别说明“可见性第一条和第二条”
实例三
package p3;
class MyObject3 extends Test3 {
}
package p33;
public class Test3 {
public static void main(String args[]) {
MyObject3 obj = new MyObject3();
obj.clone(); // Compile OK ------(1)
}
}
clone()方法来自于Test3,可见包为p33以及子类MyObject3
注意:如果MyObject3没有重写clone()方法,则沿着extends关键字一直向上找到基类
实例四
package p4;
class MyObject4 extends Test4 {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package p44;
public class Test4 {
public static void main(String args[]) {
MyObject4 obj = new MyObject4();
obj.clone(); // Compile Error -----(1)
}
}
clone()方法来自于MyObject4类,可见于package p4及其子类
注意:和实例三区分开来,因为MyObject4类重写了clone()方法,所以clone()方法来自于MyObject4类
实例五
package p5;
class MyObject5 {
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
public class Test5 {
public static void main(String[] args) throws CloneNotSupportedException {
MyObject5 obj = new MyObject5();
obj.clone(); // Compile OK ----(1)
}
}
clone()方法来自于MyObject5类,可见于package p5及其子类,Test5类刚好在package p5包内,所以编译通过
实例6
package p6;
class MyObject6 extends Test6{}
public class Test6 {
public static void main(String[] args) {
MyObject6 obj = new MyObject6();
obj.clone(); // Compile OK -------(1)
}
}
clone()方法来自于Test6类,可见于package p6以及Test6的子类,Test6在package p6内所以编译通过
实例七
package p7;
class MyObject7 extends Test7 {
public static void main(String[] args) {
Test7 test = new Test7();
test.clone(); // Compile Error ----- (1)
}
}
public class Test7 {
}
clone()方法来自于object类,clone方法可见于java.lang类及其子类Test7,MyObject7不在此范围内,所以编译错误
注意:任何没有用extends的类A的基类都是object类,则所属包为java.lang及其子类为A
总结
一、Protected用法正误判断三步骤
1.先判断clone()方法来自于哪个类(记为A类)
1.1 extends关键字的处理-是否重写
1.2 实例7的情况要特别注意-任何类without extends的基类都是object
2.判断调用clone()方法的类(记为类B)是否符合”可见性的第一个条件“
2.1 是否在A类所在的包中,是则可见;不是则判断2.2
2.2 是否是A类的子类,是则判断3;不是则不可见
3.如果不在包中但是A的子类则进一步判断
3.1 clone()方法是通过A类的实例调用,则不可见
3.2 clone()方法是通过B类的实例调用,则可见
二、
1.父类中声明为public的方法在子类中必须为public
2.父类中声明为Protected的方法在子类中要么为public,要么为Protected
——————————————————————————————————————
补充:参考2
1.不同包下,在子类中不能通过另一个子类引用访问共同基类的Protected方法
2.父类为static Protected修饰类——只要是子类,不管是不是同一包下,均可访问;不同包下,非子类不能访问——也就是比不加static的情况中,子类的判断情况更简单了
注:static类型的变量或方法直接通过”类名.方法名“来访问
网友评论