Java protected 关键字跨包情况下的访问控制

  1. 基类的 protected 成员是包内可见的,并且对其子类可见;
  2. 若子类 S 与基类 C 不在同一包中,那么在子类 S 中,只能访问 S 的实例及 S 的子类实例从基类 C 继承而来的 protected 成员。

以访问方法为例说明第二点:

// 示例一
package p1;
public class FatherInP1 {
    protected void protectedMethod() {}    // 父类 FatherInP1 中的 protected 方法
}

package p1;
public class Son1InP1 extends FatherInP1 {}

package p2;
public class Son2InP2 extends FatherInP1{}

package p1;
public class Test {
    public static void main(String[] args) {
        Son1InP1 son1InP1 = new Son1InP1();
        son1InP1.protectedMethod(); // Compile OK     ----(1)
        son1InP1.clone(); // Compile Error     ----(2)

        Son2InP2 son2InP2 = new Son2InP2();    
        son2InP2.protectedMethod(); // Compile OK     ----(3)
        son2InP2.clone(); // Compile Error     ----(4)
    }
}

(1)(3):其中的 protectedMethod() 方法从类 FatherInP1 继承而来,其可见性是包 p1 及其子类(Son1InP1 和 Son2InP2),由于调用 protectedMethod() 方法的类 Test 所在的包也是 p1,因此 (1)(3) 处编译通过。

(2)(4):其中的 clone() 方法的可见性是 java.lang 包及其所有子类,对于语句 son1InP1.clone();son2InP2.clone();,二者的 clone() 在类 Son1InP1、Son2InP2 中是可见的,但对 Test 是不可见的(因为 Test 不在 java.lang 包下,只能够访问自身及其子类实例从 Object 类继承到的 clone 方法),因此 (2)(4) 处编译不通过。

// 示例二
package p1;
class FatherInP1 {
    protected Object clone() throws CloneNotSupportedException{
       return super.clone();
    }
}

package p2;
public class SonInP2 extends FatherInP1 {
    public static void main(String args[]) {
       FatherInP1 fatherInP1 = new FatherInP1();
       fatherInP1.clone(); // Compile Error         ----(1)

       SonInP2 sonInP2 = new SonInP2();
       sonInP2.clone(); // Compile OK         ----(2)
    }
}

(1):clone() 方法来自于类 FatherInP1 本身,因此其可见性为包 p1 及 FatherInP1 的子类,虽然 SonInP2 是 FatherInP1 的子类,但在 SonInP2 中不能访问基类 FatherInP1 的 protected 方法 clone()(因为 SonInP2 不在 p1 包下,只能够访问其自身及其子类从 FatherInP1 类继承到的 clone 方法,而不能够访问 FatherInP1 实例及其他 FatherInP1 子类实例中受保护的 clone 方法),因此编译不通过。

(2):由于在 SonInP2 中访问的是其本身实例从基类 FatherInP1 继承来的的 clone(),因此编译通过。

// 示例三
package p1;
class SonInP1 extends FatherInP2 {
}

package p2;
public class FatherInP2 {
  public static void main(String args[]) {
    SonInP1 sonInP1 = new SonInP1();
    sonInP1.clone();   // Compile OK     ------(1)
  }
}

(1):clone() 方法来自于 Object 类,其可见性为包 java.lang 及其子类,子类 FatherInP2 不在 java.lang 包下,能够访问其自身及其子类从 Object 类继承到的 clone 方法,(1)正是尝试在父类 FatherInP2 中访问其子类实例继承到的 clone 方法,编译通过。

// 示例四
package p1;
class SonInP1 extends FatherInP2 {
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

package p2;
public class FatherInP2 {
  public static void main(String args[]) {
    SonInP1 sonInP1 = new SonInP1();
    sonInP1.clone(); // Compile Error      -----(1)
  }
}

(1):clone() 方法来自于类 SonInP1,其可见性为包 p1 及其子类(此处没有子类),而类 FatherInP2 在包 p2 中且不是 SonInP1 的子类,因此不满足可见性,编译不通过。

// 示例五
package p1;

class FatherInP1 {
    protected Object clone() throws CloneNotSupportedException{
       return super.clone();
    }
}
public class SonInP1 {
    public static void main(String[] args) throws CloneNotSupportedException {
       FatherInP1 fatherInP1 = new FatherInP1();
       fatherInP1.clone(); // Compile OK        ----(1)
    }
}

(1):clone() 方法来自于类 FatherInP1,其可见性为包 p1 及其子类 (此处没有子类),而类 SonInP1 也在包 p1 中,因此满足可见性,编译通过。

// 示例六
package p1;

class SonInP1 extends FatherInP1{}

public class FatherInP1 {
  public static void main(String[] args) {
    SonInP1 sonInP1 = new SonInP1();
    sonInP1.clone();        // Compile OK   -------(1)
  }
}

(1):clone() 方法来自于类 Object,其可见性为包 java.lang 包及其子类,子类 FatherInP1 不在 java.lang 包下,能够访问其自身及其子类从 Object 类继承到的 clone 方法,而(1)正是尝试在父类 FatherInP1 中调用其子类 SonInP1 继承到的 clone 方法,编译通过。

// 示例七
package p1;

class SonInP1 extends FatherInP1 {
    public static void main(String[] args) {
        FatherInP1 fatherInP1 = new FatherInP1();
        fatherInP1.clone(); // Compile Error   ----- (1)
  }
}

public class FatherInP1 { }

(1):clone() 方法来自于类 Object,因此该 clone() 方法可见性为包 java.lang 及其子类,SonInP1 能够访问自身及其子类从 Object 继承到的 clone 方法,由于类 FatherInP1 不是 SonInP1 的子类,因此不满足可见性,编译不通过。

Demo 及主要内容来自 1,但其中的解释(至少对我来说)并不准确。

其他:234

posted @ 2022-04-20 19:48  Higurashi-kagome  阅读(148)  评论(0编辑  收藏  举报