深入理解JAVA中的跨包继承

时间:2024-02-24 09:20:35

今天根据要求对集中访问控制符做了测试,在子类跨包继承的权限问题,发现有些矛盾。

代码说明:父类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;