深入理解JAVA中的跨包繼承


今天根據要求對集中訪問控制符做了測試,在子類跨包繼承的權限問題,發現有些矛盾。

代碼說明:父類Father 在packageA中  子類Child01也在packageA中  子類Child02在packageB中

下面上代碼;

 1 package packB;
 2 import packA.Father;
 3 //    本類是Father類不同包的子類
 4 public class Child02 extends Father
 5 {
 6     public static void main(String[] args) {        
 7         Father father = new Father();    
 8         System.out.println(father.public_a);    //   public修飾的成員,在不同包中子類能訪問
 9 //        System.out.println(father.protected_b);    //   protected修飾的成員,在不同包子類中不能訪問
10 //        System.out.println(father.default_c);    //   default修飾(默認)的成員,在不同包子類中不能訪問
11 //        System.out.println(father.private_d);      //   private修飾的成員,在不同包子類中不能訪問
12         
13         father.pulic_aa();    //  public修飾的方法,在不同包子類中能訪問
14 //        father.protected_bb();    //   protected修飾的方法,在不同包子類中不能訪問
15 //        father.default_cc();    //   default修飾(默認)的方法,在同包子類中不能訪問
16 //        father.private_dd();    //   private修飾的方法,在同包子類中不能訪問
17 
18 //        下面是個人對跨包繼承的深入理解,與別人的理解和說法有些矛盾     由於方法的權限和屬性一樣  就不寫了
19         
20 // 訪問方式一
21         Child02 child = new Child02();
22         child.public_a = 10;
23         child.protected_b = 20;
24 //        child.default_c = 30;    //報錯      父類該屬性對子類不可見
25 //        child.private_d = 30;    //報錯    父類該屬性對子類不可見
26         
27     }
28 // 訪問方式二
29     void test(){
30         public_a = 10;
31         protected_b = 20;
32 //        default_c = 30;    //    報錯        父類該屬性對子類不可見
33 //        private_d = 30;    //    報錯        父類該屬性對子類不可見
34     }
35 // 訪問方式三
36     void test1(){
37         super.public_a = 10;
38         super.protected_b = 20;
39 //        super.default_c = 30;    //    報錯        父類該屬性對子類不可見
40 //        super.private_d = 30;    //    報錯        父類該屬性對子類不可見
41     }
42     
43 
44 
45     
46 }

從第7行到第16行,是對在跨包子類中的Father對象進行操作,訪問結果說明只能訪問到 public修飾的屬性和方法。

就是從這里產生了矛盾,因為和之前所了解的內容有出入  故對其進行深入了解。

下面從第20行到第40行是另外的三種訪問方式 和之前了解的權限相匹配;

  方式一:是訪問子類對象中從父類繼承的屬性,發現父類中protected修飾的屬性可以被訪問,此時訪問的是子類對象的屬性;

  方式二:是訪問子類中從父類繼承的屬性,發現父類中protected修飾的屬性可以被訪問,此時訪問的屬性是子類的屬性;

  方式三:通過super來調用父類的屬性,這里會讓人覺得這個肯定是父類調用自身的屬性了;

  於是我對代碼進行改造,讓結果變得更明顯:

Father 類

 1 package packA;
 2 //本類是參考類,用來和child、uncle了來測試
 3 public class Father {
 4 //    成員變量
 5     public int public_a = 1;  6     protected int protected_b = 2;  7     int default_c = 3;  8     private int private_d = 4;  9 //    方法
10     public void pulic_aa(){
11         
12     }
13     protected void protected_bb(){
14         
15     }
16     void default_cc(){
17         
18     }
19     private void private_dd(){
20         
21     }
22     
23     public static void main(String[] args) {
24 
25     }
26 
27 }

Child02類

 

 1 package packB;
 2 import packA.Father;
 3 //    本類是Father類不同包的子類
 4 public class Child02 extends Father
 5 {
 6     public static void main(String[] args) {        
 7         Father father = new Father();  8         System.out.println(father.public_a);    //   public修飾的成員,在不同包中子類能訪問
 9 //        System.out.println(father.protected_b);    //   protected修飾的成員,在不同包子類中不能訪問
10 //        System.out.println(father.default_c);    //   default修飾(默認)的成員,在不同包子類中不能訪問
11 //        System.out.println(father.private_d);      //   private修飾的成員,在不同包子類中不能訪問
12         
13         father.pulic_aa();    //  public修飾的方法,在不同包子類中能訪問
14 //        father.protected_bb();    //   protected修飾的方法,在不同包子類中不能訪問
15 //        father.default_cc();    //   default修飾(默認)的方法,在同包子類中不能訪問
16 //        father.private_dd();    //   private修飾的方法,在同包子類中不能訪問
17 
18 //        下面是個人對跨包繼承的深入理解,與別人的理解和說法有些矛盾     由於方法的權限和屬性一樣  就不寫了
19         
20 //        訪問方式一:
21         Child02 child = new Child02();
22         child.public_a = 10;
23         child.protected_b = 20;
24 //        child.default_c = 30;    //報錯      父類該屬性對子類不可見
25 //        child.private_d = 30;    //報錯    父類該屬性對子類不可見
26         child.test();
27         child.test1();
28     }
29 //     訪問方式二:
30     void test(){
31         public_a = 10; 32         protected_b = 20;
33         System.out.println(public_a+"*"+protected_b);
34         System.out.println(super.public_a+"*"+super.protected_b);
35         Father father01 = new Father(); 36         System.out.println(father01.public_a);
37 //        default_c = 30;    //    報錯        父類該屬性對子類不可見
38 //        private_d = 30;    //    報錯        父類該屬性對子類不可見
39     }
40 //    訪問方式三:
41     void test1(){
42         super.public_a = 10;
43         super.protected_b = 20;
44 //        super.default_c = 30;    //    報錯        父類該屬性對子類不可見
45 //        super.private_d = 30;    //    報錯        父類該屬性對子類不可見
46     }
47     
48 
49 
50     
51 }

 

輸出結果:

 

從結果可以明顯的看出通過super方式得到是Child02類的public_a的屬性,並不是Father類的public_a的屬性;

  強勢插入一段自己對super的理解,super是子類對父類的一個引用,指向子類從父類繼承下來的屬性,若指向父類中子類沒有繼承的屬性則會報錯,另外如果子類對繼承的屬性進行重寫,則super指向父類的該屬性。

我們可以看看和Father同包的Child01類里面指向沒有繼承的屬性是不是可以:

 1 package packA;
 2 //    本類是Father類同包的子類
 3 public class Child01 extends Father
 4 {
 5     public static void main(String[] args) {
 6         Father father = new Father();    
 7         System.out.println(father.public_a);    //測試證明   public修飾的成員,在同包子類中能訪問
 8         System.out.println(father.protected_b);    //測試證明   protected修飾的成員,在同包子類中能訪問
 9         System.out.println(father.default_c);    //測試證明   default修飾(默認)的成員,在同包子類中能訪問
10 //        System.out.println(father.private_d);  測試證明   private修飾的成員,在同包子類中不能訪問
11         
12         father.pulic_aa();    //測試證明   public修飾的方法,在同包子類中能訪問
13         father.protected_bb();    //測試證明   protected修飾的方法,在同包子類中能訪問
14         father.default_cc();    //測試證明   default修飾(默認)的方法,在同包子類中能訪問
15 //        father.private_dd();    測試證明   private修飾的方法,在同包子類中不能訪問
16     }
17     void test(){
18         super.public_a = 10;
19         super.protected_b = 20;
20         super.default_c = 30;    
21 //        super.private_d = 30;    //    報錯        父類該屬性對子類不可見
22     }
23 }

這樣就充分說明了,屬性的繼承和super使用條件,也就是方式三中訪問的屬性其實是Child02類的屬性,也就是說在跨包的子類里面訪問父類的屬性的還是只有public;

同時子類繼承權限因為跨包影響,從pulic,protected和default 變成 pulic和protected;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM