Java子类继承的小陷阱

//对于初学者来说,这个例子应该算是个比较典型的陷阱了。先把结论写在前面,看完例子可以回过来体会~

结论:【对象是承载方法的载体。句柄决定属性的访问。】

Exp 1:TestTree.java

 1 class Tree{
 2     int Height = 10;
 3     public void Watering(){
 4         Height ++;
 5     }    
 6 }
 7 
 8 public class TestTree extends Tree{
 9     int Height = 2;
10     public void Watering(){       
11         Height += 3;
12     }
13     public static void main(String[] args)
14     {
15         Tree t = new TestTree();
16         t.Watering();
17         System.out.println(t.Height);
18     }
19 }

运行结果:10

这里15行new了一个子类对象,但句柄是父类的(多态)。

父类和子类有同名属性Height(两者相互独立),有同名方法Watering。这时候,父类的方法相当于被子类覆盖,所以16行的执行会使得Height调用子类的方法。要小心的是:这里的Height是谁的属性取决于执行的是谁的方法,比如这里是子类的方法,那么就到子类里面找是否有Height属性,有的话就是使用这个子类属性。若没有则使用父类的Height属性。

但这里输出的结果是t.Height, 这个Height直接是访问父类的属性,所以输出的结果直接是10。

 

再来稍加改动,如果将第九行注释掉,即把子类里的Height属性删去,如下:

Exp 2:

 1   class Tree{
 2       int Height = 10;
 3       public void Watering(){
 4           Height ++;
 5       }    
 6   }
 7   
 8   public class TestTree extends Tree{
 9       //int Height = 2;
10       public void Watering(){       
11          Height += 3;
12      }
13      public static void main(String[] args)
14      {
15          Tree t = new TestTree();
16          t.Watering();
17          System.out.println(t.Height);
18      }
19  }

运行结果:13

这里子类的方法会使用父类的属性Height,然后执行子类的方法加3,最后输出父类的属性(此时已经被修改)即13。

回到初始结论,句柄决定了属性的访问,是父类的句柄最后输出一定是父类的属性。

 

至于方法,这里是因为父类的方法被覆盖,所以使用子类的方法。若不存在方法覆盖,仅修改第10行如下:

Exp 3:

 1    class Tree{
 2        int Height = 10;
 3        public void Watering(){
 4            Height ++;
 5        }    
 6    }
 7    
 8    public class TestTree extends Tree{
 9       int Height = 2;
10       public void Fertilizing(){       
11          Height += 3;
12      }
13      public static void main(String[] args)
14      {
15          Tree t = new TestTree();
16          t.Watering();
17          System.out.println(t.Height);
18      }
19  }

运行结果:11

这里的方法显然是(继承自)父类的,那么调用的属性是父类的Height=10。结果便为11了。

 

若将上例16行改为:t.Fertilizing(); 那么便会报错,猜测是父类里面并没有这个方法~具体为什么暂时不清楚~后续学习吧

当然,这里还可以扩展出许多情况,如修饰符、方法重载,大可自行修改,就暂时不说啦。

 

posted @ 2017-03-19 18:33  重头学前端  阅读(167)  评论(0编辑  收藏  举报