日期:2014-05-20  浏览次数:20707 次

关于java中的多态的理解
我们知道在java中我们可以声明超类的变量来引用子类的对象,我们知道被声明为超类变量的实际引用是子类的对象,而在调用方法时根据隐式参数来确定调用哪个对象的方法,那么为什么我们不能够用这个变量调用超类中没有定义而在子类新写的方法呢?
  比如我们写两个类
  class Father
  {
  protected void showInfo()
  {
  System.out.println("Father");
  }

  }
  class Son extends Father
  {
  protected void showInfo()
  {
  System.out.println("Father");
  }
  void play()
  {
  System.out.println("play");
  }
  
  }
  public class TestSon
  {
  Father fa=new Son();
  fa.showInfo();
  fa.play();//fa是对Son对象的一个引用,为什么这个方法不能被调用?
  }
  麻烦各位高手能够给我这个菜鸟讲讲这个问题,越透彻越好,能讲到内存机制更好!

------解决方案--------------------
从内存来考虑:
当之类被实例化后会先实例出一个父类。因为子类中有一个隐藏的引用super会指向父类实例,由于子类中包含了父类的实例,所以子类可以调用父类的方法.
而Father fa=new Son();子类 只是指向了new son()中实例的父类实例对象.所以只能调用父类的方法,而不能调用之类的方法。
------解决方案--------------------
动态方法调用
------解决方案--------------------
探讨
从内存来考虑:
当之类被实例化后会先实例出一个父类。因为子类中有一个隐藏的引用super会指向父类实例,由于子类中包含了父类的实例,所以子类可以调用父类的方法.
而Father fa=new Son();子类 只是指向了new son()中实例的父类实例对象.所以只能调用父类的方法,而不能调用之类的方法。

------解决方案--------------------
子类的对象,自动被认为是父类的对象。
父类的对象,不能自动被认为是父类的对象。它必须强制转换成子类的对象之后,才可作为句柄,调用子类的方法。

你的有主方法的驱动类:TestSon, 应改写成如下代码,方可运行:

public class TestSon 

public static void main(String args[]) {
Father fa=new Son(); //子类的对象,自动被认为是父类的对象。结果fa为Father类
fa.showInfo(); 
((Son) fa).play();//父类的对象,必须强制转换成子类的对象之后,才可调用子类的方法。

}
------解决方案--------------------

Father fa=new Son(); 
fa.showInfo(); 
fa.play();//fa是对Son对象的一个引用,为什么这个方法不能被调用? 



----------------------------------------

这里涉及了向上转型 的问题...

Father fa=new Son();
我认为是这里创建了一个Son对象,并把得到的引用立即赋值给Father..

其实楼主的想法是相反了

我们知道,对象既可以作为它自己本身的类型使用,也可以作为它的基类型使用,
Father fa=new Son();
就是典型的向上转型(把某个对象的引用视为对基类的引用)

所以这里应该是对Father的引用,并不是对Son的引用,所以不可能使用play()的..

楼主可以看看有关"向上转型"的资料