java继承中的几点注意事项

继承是面向对象语言的一个重要特征,在进行大型项目开发的时候其优点尤其明显,这里对java中应用继承时的几点注意事项(容易出错的地方)进行了总结。笔者本打算将这几种现象从基本原理上解释一下,但是想来想去都感觉无从下手,因为需要读者比较了解java虚拟机的内部机制,很多东西比较抽象,所以看到这篇文章的读者记住下面这几种现象就行了,如果想深入理解其本质原理,建议大家读一下《深入java虚拟机》这本书。

一、最常见的一种,对象的上转型对象:即运行时多态(这种情况相信大家都知道,为了文章的完整性也放到了这里)

示例:

[java]  view plain copy
  1. public class TestExtend{  
  2.     public static void main(String args[]){  
  3.         Person p=new Person();  
  4.         p.disp();  
  5.         Student s=new Student();  
  6.         p=s;      
  7.         p.disp();  
  8.     }  
  9. }  
  10.   
  11. class Person{  
  12.     int a;  
  13.     public Person(){  
  14.         a=1;  
  15.     }  
  16.     public void disp(){  
  17.         System.out.println(a);  
  18.     }  
  19. }  
  20.   
  21. class Student extends Person{  
  22.     int a;  
  23.     public Student(){  
  24.         a=2;  
  25.     }  
  26.     public void disp(){  
  27.         System.out.println(a);  
  28.     }  
  29. }  

解析:上面的程序会先输出1,然后输出2。

输出1时,p指向的就是Person的实例,调用Person类的disp()方法,输出Person实例的属性a=1;输出2时,p指向的是Student的实例,调用Student的disp()方法,输出Student实例的属性a=2。

 

二、情况二

示例:

[java]  view plain copy
  1. public class TestExtend{  
  2.     public static void main(String args[]){  
  3.         Student s=new Student();  
  4.         s.disp();  
  5.     }  
  6. }  
  7.   
  8. class Person{  
  9.     int a;  
  10.     public Person(){  
  11.         a=1;  
  12.     }  
  13.     public void disp(){  
  14.         System.out.println(a);  
  15.     }  
  16. }  
  17.   
  18. class Student extends Person{  
  19.     int a;  
  20.     public Student(){  
  21.         a=2;  
  22.     }  
  23. }  

解析:运行上面的程序,输出的是1还是2?你会看到输出的是1!

上面的程序中Person和Student类中都有a属性,我们定义了一个Student的对象s,调用s的disp()方法输出的不是Student的a而是Person的a。相信很多人在运行程序前都会觉得应该输出2,但结果告诉我们输出的就是1!子类Student虽然覆盖了父类的属性a,但子类没有重写父类的disp()方法,对象s调用disp()方法时调用的依然是父类的方法,而父类方法访问的依然是父类的a,而不是子类的a。这里或者重写父类的disp()方法,或者将Student中的int a;注释掉才能输出2!

其实上面程序在逻辑上是有问题的,既然继承了父类的属性,就不应该在子类中从新定义一遍,子类中可以增加属性,但是重写属性没有什么意义!这里这样演示,是想说明这样一种情况。

 

三、情况三:类属性没有多态

示例:

[java]  view plain copy
  1. public class TestExtend{  
  2.     public static void main(String args[]){  
  3.         Person p;  
  4.         Student s=new Student();  
  5.         p=s;  
  6.         System.out.println(p.a);      
  7.     }  
  8. }  
  9.   
  10. class Person{  
  11.     int a;  
  12.     public Person(){  
  13.         a=1;  
  14.     }  
  15.     public void disp(){  
  16.         System.out.println(a);  
  17.     }  
  18. }  
  19.   
  20. class Student extends Person{  
  21.     int a;  
  22.     public Student(){  
  23.         a=2;  
  24.     }  
  25.     public void disp(){  
  26.         System.out.println(a);  
  27.     }  
  28. }  

解析:上面的程序输出的是1;

即使在Student类中从新定义了一遍a,并且p指向了Student的实例,上面输出的是依然是Person的a而不是Student的a,属性是没有多态现象的。和上面一样,在子类中定义父类中已经定义了的属性,是没有意义的,既然父类已经有了某个属性,子类直接继承就是了,重写一遍从道理上根本说不清。很多初学者,对继承理解不是很透彻,很多论坛上都在问很多关于在子类中复写了父类的属性,访问中遇到的问题,其实这是自找麻烦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值