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

请教一个java多态的问题
package com.asp;
 public class Test1 {
 public static void main(String[] args) {
   Fu a = new Zi();
   a.b();
 }
 }
 class Fu {
 public void a() {
   System.out.println("fu---a");
 }
public void b() {
   System.out.println("fu---b");
   a();
 }
 }
 class Zi extends Fu {
 public void a() {
   System.out.println("zi----a");
 }
 public void b() {
   System.out.println("zi----b");
 super.b();
   System.out.println(super.toString());
 }
 }
 
运行的结果是
 zi----b
 fu---b
 zi----a
 com.asp.Zi@1fc4bec
 我有个不明白的地方 红色的代码super.b()不是相当于调用父类对象的b方法吗 
父类对象里面b方法又调用了a方法  那不是应该也是调用的父类的a方法吗
 所以我感觉运行结果应该是
 zi----b
 fu---b
 fu---a
 还有我最后打印的super.toString()也应该返回一个父类的实例啊  怎么返回了子类的实例了

------解决方案--------------------
super.b()方法是调用父类的b方法,在父类的b方法里调用a()方法,因为a()方法被重写了,所以调用的是子类的a()方法,还有就是在构造方法里调用时也是如此!
------解决方案--------------------
父类去new一个子类的时候,它会现在子类当中去找,如果找到了就用子类的,没找到的话就会用父类的。
------解决方案--------------------
第一个问题,在父类中b方法调用a方法,默认是使用this调用,即this.a(),this指向当前实例,所以调用子类的a方法,打印zi --- a
------解决方案--------------------
第三个输出结果是这样的:既然你重写了a方法,在父类引用指向子类对象的时候,构造方法完成的时候,你就应该认为内存中子类对象里面有个引用指向了a方法,你实际上new出来的是什么对象,这个引用就指向该对象的a方法,所以实际调用的是子类的a方法,
toString方法,你在父类中没有写,那么因为任何类都是Object的子类,所以你实际上调用的是Object中的toString方法,你看下api对这个方法的描述就懂了.