java protected存取權限

來源:互聯網
上載者:User

其實這個問題,就是一句話,那就是“與基類不在同一個包中的子類,只能訪問自身從基類繼承而來的受保護的成員,而不能訪問基類執行個體本身的受保護的成員”。

 

 

     原創作品,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本聲明。否則將追究法律責任。http://zhangjunhd.blog.51cto.com/113473/19287 本文分析一下protected 存取權限。author: ZJ 2007-3-5Blog: [url]http://zhangjunhd.blog.51cto.com/[/url] 來談談protected存取權限問題。看下面樣本1:Test.java
class MyObject {} public class Test {    public static void main(String[] args) {       MyObject obj = new MyObject();       obj.clone(); // Compile error.    }}
此時出現上文提到的錯誤:The method clone from the type Object is not visiuable.我們已經清楚Object.clone()是protected方法。這說明,該方法可以被同包(java.lang)下和它(java.lang.Object)的子類訪問。這裡是MyObject類(預設繼承java.lang.Object)。同樣Test也是java.lang.Object的子類。但是,不能在一個子類中訪問另一個子類的protected方法,儘管這兩個子類繼承自同一個父類。再看樣本2:Test2.java
class MyObject2 {    protected Object clone() throws CloneNotSupportedException {       return super.clone();    }} public class Test2 {    public static void main(String[] args) throws CloneNotSupportedException {       MyObject2 obj = new MyObject2();       obj.clone(); // Compile OK.    }}
這裡,我們在MyObject2類中覆蓋(override)父類的clone()方法,在另一個類Test2中調用clone()方法,編譯通過。編譯通過的原因顯而易見,當你在MyObject2類中覆蓋clone()方法時,MyObject2類和Test2類在同一個包下,所以此protected方法對Test2類可見。分析到這裡,我們在回憶一下Java中的淺複製與深複製文中,章節2.2中的聲明, 在衍生類別中覆蓋基類的clone() 方法,並聲明為public 現在明白這句話的原因了吧(為了讓其它類能調用這個類的clone()方法,重載之後要把clone()方法的屬性設定為public)。下面再來看樣本3:Test3.java
package 1class MyObject3 {protected Object clone() throws CloneNotSupportedException {       return super.clone();    }} package 2public class Test3 extends MyObject3 {    public static void main(String args[]) {       MyObject3 obj = new MyObject3();       obj.clone(); // Compile error.       Test3 tobj = new Test3();       tobj.clone();// Complie OK.    }}
這裡我用Test3類繼承MyObject3,注意這兩個類是不同包的,否則就是樣本2的情形。在Test3類中調用Test3類的執行個體tobj的clone()方法,編譯通過。而同樣調用MyObject3類的執行個體obj的clone()方法,編譯錯誤!意想不到的結果,protected方法不是可以被繼承類訪問嗎?必須明確,類Test3確實是繼承了類MyObject3(包括它的clone方法),所以在類Test3中可以調用自己的clone方法。但類MyObject3的protected方法對其不同包子類Test3來說,是不可見的。對於樣本1的解釋就是——雖然MyObject與Test屬於同一個包,但受保護的clone方法來自java.lang.Object類型,而在Test中,其基類Object的受保護方法是不可見的。

對於樣本2的解釋就是——MyObject與Test在同一個包中,受保護的clone方法來自MyObject本身,所以它對Test而言是可見的。另外在這個樣本中,還說明了super關鍵字對於基類受保護的成員的調用是個語言設計之中的“例外”。

樣本3很簡單了,就是企圖跨越不同的包,從子類中調用基類執行個體的受保護方法。

最後,我在補充兩個例子:
樣本4:(針對樣本1的修改)
class MyObject extends Test{}
public class Test {
  public static void main(String[] args) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile ok.
  }
}
為什麼可見呢?因為MyObject的clone方法繼承自Test,而Test做為相對於Object的子類,是可以訪問繼承而來的屬於它自己的受保護方法的~

樣本5:
package 1
class MyObject extends Test {
}

package 2
public class Test {
  public static void main(String args[]) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile OK
  }
}
雖然處於不同的包,但子類的受保護方法實際上繼承自父類,父類的自己的受保護方法對自己可見,其原理同樣本4.

樣本6:
package 1
class MyObject extends Test {
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

package 2
public class Test {
  public static void main(String args[]) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile error!
  }
}
不同包中子類本身的受保護方法當然不可能對父類可見~

再補充樣本7:
package a;
class MyObject extends Test {
    public static void main(String[] args) {
    Test test = new Test();
    test.clone(); // Compile error.
  }
}
package a;
public class Test {
 
}
同一個包中,父類執行個體的clone方法在子類中依然不可見,原理同樣本1,就是因為父類的clone方法,實際上來自java.lang.Object

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.