黑马程序员技术交流社区

标题: 对java中的多态的理解问题 [打印本页]

作者: 张少威    时间: 2012-6-5 11:32
标题: 对java中的多态的理解问题
我们知道在java中我们可以声明超类的变量来引用子类的对象,我们知道被声明为超类变量的实际引用是子类的对象,而在调用方法时根据隐式参数来确定调用哪个对象的方法,
那么为什么我们不能够用这个变量调用超类中没有定义而在子类新写的方法呢?

  比如我们写两个类
  1. class Father
  2. {
  3.         protected void showInfo()
  4.         {
  5.                 System.out.println("Father");
  6.         }

  7. }
  8. class Son extends Father
  9. {
  10.         protected void showInfo()
  11.         {
  12.                 System.out.println("Father");
  13.         }
  14.         void play()
  15.         {
  16.                 System.out.println("play");
  17.         }

  18. }
  19. public class TestSon
  20. {
  21.         Father fa=new Son();
  22.         fa.showInfo();
  23.         fa.play();//<font color="#ff0000">fa是对Son对象的一个引用,为什么这个方法不能被调用?</font>
  24. }
复制代码
麻烦各位高手能够给我这个菜鸟讲讲这个问题,越透彻越好,能讲到内存机制更好!


作者: 张洁    时间: 2012-6-5 11:51
额,内存的话,从内存方面来说:
当之类被实例化后会先实例出一个父类。
因为子类中有一个隐藏的引用super会指向父类实例,由于子类中包含了父类的实例,所以子类可以调用父类的方法。
而Father fa=new Son();子类 只是指向了new son()中实例的父类实例对象.所以只能调用父类的方法,而不能调用之类的方法。

关于楼主滴问题:fa是对Son对象的一个引用,为什么这个方法不能被调用?
这里涉及了向上转型,
Father fa=new Son();
我认为是这里创建了一个Son对象,并把得到的引用立即赋值给Father..
其实楼主的想法是相反了,
我们知道,对象既可以作为它自己本身的类型使用,也可以作为它的基类型使用,
Father fa=new Son();
就是典型的向上转型(把某个对象的引用视为对基类的引用)
所以这里应该是对Father的引用,并不是对Son的引用,所以不可能使用play()的~


作者: 黑马张扬    时间: 2012-6-5 11:54
本帖最后由 黑马张扬 于 2012-6-5 11:56 编辑
  1. Father fa=new Son();
复制代码

在jvm载入类的时候同时也记录了该类的方法,可以理解为同时保存了一个方法表,

因为fa是Father类型的,所以方法表中记录了Father的方法。

所以只能调用父类的中特有的方法,或是子类覆盖父类的方法。而不能调用子类中特有的方法。

作者: 张少威    时间: 2012-6-5 11:55
张洁 发表于 2012-6-5 11:51
额,内存的话,从内存方面来说:
当之类被实例化后会先实例出一个父类。
因为子类中有一个隐藏的引用super ...

good,解释的很好




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2