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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章