A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴琼 中级黑马   /  2012-6-17 17:11  /  1818 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class A {
  void fun1() {
    System.out.println(fun2());
  }
  int fun2() {
    return 123;
  }
}
class B extends A {
  int fun2() {
    return 456;
  }
  public static void main(String argv[]) {
    A a;
    B b = new B();
b.fun1();//子类创建自己对象,调用的是fun2()这个我知道.
    a = b;//
a.fun1();//为什么多态中父类对象指向子类对象.调用的还是fun2();
  }
}

6 个回复

正序浏览
本帖最后由 wyl530274554 于 2012-6-17 21:31 编辑

成员函数在多态调用时,运行时,看右边

即new的是谁,就调用谁的方法。

a=b,
在这里a,b指向了同一个对象new B();
所以就调用B类里的方法fun2()
回复 使用道具 举报
  1. a = b
复制代码
楼主这句话在java中叫做向上转型.
所以既然是子类对象赋给了父类引用,
  1. a.fun1();
复制代码
那么调用的其实是调用的是子类复写之后的方法.
所以输出的是子类的456.而不是父类的123.

点评

精辟!  发表于 2012-6-17 17:53

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
a=b  这个不是a指向b  而是 a等于b  ,所以你下一行代码a.fun1()就相当于b.fun1()    这时就是子类b调用继承自a的fun1()方法,因为在子类b中重载了fun2()方法,打印出来当然就是456了。
另外楼主写代码加强点层次感,看的真的很费劲。
回复 使用道具 举报
  1. class A {
  2.         void fun1() {
  3.                 System.out.println(this.getClass().getName());  //输出B
  4.                 System.out.println(this.fun2());
  5.         }
复制代码
回复 使用道具 举报
所以a实际上引用的是子类对象,必然调用子类中的方法
回复 使用道具 举报
当变量的编译时类型和运行时类型不同时,通过该变量访问它所引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。
通过该变量调用它所引用的对象的实例方法时,该方法行为将由它实际所引用的对象来决定。
此时通过父类声明的对象去调用一个父类中并没有存在的一个方法,编译肯定是通不过的。当父类也有这个方法的时候,去调用,那么它将去执行它实际所引用的对象中的方法。

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马