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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 心灵之歌 中级黑马   /  2013-8-6 09:48  /  1206 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨兴庭 于 2013-8-6 19:05 编辑

下面这段代码的运行结果为什么是:456,456?为什么?


class A {
                void fun1() {
                      System.out.println(fun2());
                }

                int fun2() {
                        return 123;
                }
        }

         public class B extends A {
                int fun2() {
                         return 456;
                 }

                public static void main(String args[]) {
                        B b = new B();
                        b.fun1();
                        A a = b;
                        a.fun1();
                }
        }

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

6 个回复

倒序浏览
首先:类B继承了类A并覆盖了类A的fun2方法,哪么不管是建立类A的对象还是类B的对象,运行时,都是走的子类方法,
  B b = new B();
  b.fun1();//走的子类中的fun2方法,打印456
  A a = b;//这里用到的是多态,
  a.fun1();//因为子类覆盖了父类的方法,所以走的还是子类的fun2,结果当然还是456
总之一句话:当子类覆盖父类方法时,哪么运行时,走的都是子类方法

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
这里:“public class B extends A {
                int fun2() {
                         return 456;
                 }
....”
你的B继承了A,但是在B里面,你复写了fun2()方法,
当你在主函数中B b = new B(); b调用了A里的fun1(),而fun1()又输出的是fun2()的返回值,
而你已经复写了fun2(),所以fun1()就去调用你复写后的fun2(),于是这里返回第一个456.

然后,a还是调用fun1(),fun1()还是调用了复写后的fun2()方法,返回还是456.

还有一点,我调试的时候,需要把“public class B extends A”前面的public去掉才可以。不知为何

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 逆袭的风 于 2013-8-6 10:33 编辑
  1. class A {
  2.                 void fun1() {
  3.                       System.out.println(fun2());
  4.                 }

  5.                 int fun2() {
  6.                         return 123;
  7.                 }
  8.         }

  9.          public class B extends A {//B继承后重写A中fun2方法
  10.                 int fun2() {
  11.                          return 456;
  12.                  }

  13.                 public static void main(String args[]) {
  14.                         B b = new B();
  15.                         b.fun1();
  16.                         A a = b;//多态(父类变量引用子类对象)
  17.                         a.fun1();
  18.                                                 A a1=new A();
  19.                                                 a1.fun1();
  20.                 }
  21.         }
复制代码
试试上面的代码

Unnamed.png (4.63 KB, 下载次数: 0)

Unnamed.png

评分

参与人数 1技术分 +2 收起 理由
杨兴庭 + 2 赞一个!

查看全部评分

回复 使用道具 举报
  你这个是多态的问题
第一个是    子类 对象名 = new  子类;你调用的方法,父类也有,所以就是一般的覆盖了。
定义多态  一般是 :父类    对象名 = new  子类;
                           左边                         右边;    当你在调用子类的非静态方法的时候编译这个方法是的时候,要看这个方法父类有没有存在,在运行的时候,执行的是子类的方法。 总结就是编译时看左边,运行时看右边。
在附赠你 一些其他规则:  多态中,如果是调用静态方法,或者成员变量的时候,左边是什么类,就执行什么类的方法。就是编译,运行都看左边。
调用

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
b实例化后由于继承自A类调用fun1方法,再调用fun2方法,这时继承A类的fun2方法被B所重写所以显示456
a由子类所实例化,所以调用fun1方法后再调用fun2方法时用的为B类所重写后的方法,所以显示456
  1. public class Test {

  2.         public static void main(String args[]) {
  3.                 B b = new B();
  4.                 b.fun1();
  5.             A a = b;  //此处父类对象由子类实例化,以下在调用fun1方法后再调用的fun2会指向子类重写后的方法
  6.                                     //父类引用指向子类对象
  7.             a.fun1();
  8.         }
  9. }

  10. class A {
  11.    
  12.     void fun1() {   
  13.           System.out.println(fun2());
  14.     }
  15.      // 以下是父类中的func2()方法,因为下面的子类中重写了该方法 ,
  16.       //所以在父类类型的引用中调用时,这个方法将不再有效,
  17.       //取而代之的是将调用子类中重写的func2()方法
  18.     int fun2() {
  19.             return 123;
  20.     }
  21. }

  22. class B extends A {
  23.           
  24.     int fun2() {
  25.          return 456;
  26.      }
  27. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
多态的特点:
编译时期,参阅引用型变量所属的类中是否有调用的方发,如果有,编译通过,如果没有编译失败
在运行期间:参阅对象所属的类中是否有调用的方法。
成员函数在多态调用时,编译看左边的引用所属类,运行看右边的对象类。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马