美文网首页
Protected关键字详解

Protected关键字详解

作者: 小豆oo | 来源:发表于2019-01-15 11:09 被阅读0次

参考1

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类型的变量或方法直接通过”类名.方法名“来访问

相关文章

网友评论

      本文标题:Protected关键字详解

      本文链接:https://www.haomeiwen.com/subject/gxvedqtx.html