黑马程序员技术交流社区

标题: 费解的一个题目 [打印本页]

作者: ~与狼共舞~    时间: 2013-5-23 22:08
标题: 费解的一个题目
本帖最后由 ~与狼共舞~ 于 2013-5-24 22:30 编辑
  1. class A {
  2.         void fun1() {
  3.                 System.out.println(fun2());
  4.         }

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

  9. public class B extends A {
  10.         int fun2() {
  11.                 return 678;
  12.         }

  13.         public static void main(String args[]) {
  14.                 B b = new B();
  15.                 b.fun1();
  16.                 A a = b;
  17.                 a.fun1();
  18.         }
  19. }
复制代码
这个程序的结果为什么是678,678呢?求解释...
作者: 821728010    时间: 2013-5-23 22:19
B中继承了A中的“fun1”,第一个“678”不用解释吧?a虽然是A类型的,但他实际指向的是子类对象,第二个中的fun1必须是调用B(子类)中的fun2,所以打印678!
作者: Miss小强    时间: 2013-5-23 22:32
这题目有意思;
跟自己的理解有点出入。。。
做等大神解释。。。
作者: 火之意志    时间: 2013-5-23 22:33
这里涉及多态的问题,首先多态的产生有以下前提:1、有继承关系2、有方法重写3、有父类引用指向子类对象。所以B b = new B();b.fun1();,子类对象b继承了父类的fun1()方法,就相当于子类本身也有fun1()方法了,fun1()调用fun2()方法,肯定是调用子类本身的fun2()方法;A a = b;a.fun1();这里是多态的应用,虽然子类对象赋给了父类引用,但是实质上还是在调用子类fun1()的方法,跟上面的过程一样,对于重写的方法“编译看左边,执行看右边”就可以应对这种题
               
               
作者: 吕振中    时间: 2013-5-23 22:35
  1. class A {

  2.         void fun1() {

  3.                 System.out.println(fun2());   //此处打印的是fun2()方法的返回值。

  4.         }


  5.         int fun2() {

  6.                 return 345;

  7.         }

  8. }


  9. public class B extends A {

  10.         int fun2() {         //此方法覆盖了A类的fun2()方法,所以第一个打印fun2()被覆盖后的678。

  11.                 return 678;

  12.         }


  13.         public static void main(String args[]) {

  14.                 B b = new B();

  15.                 b.fun1();

  16.                 A a = b;     //把B类型的对象引用赋值给了变量a,此时变量a的引用其实指向的是对象B,故结果与第一个值是一样的。

  17.                 a.fun1();

  18.         }

  19. }
复制代码

作者: 谢孔营    时间: 2013-5-23 22:36
01.class A {

02.        void fun1() {

03.                System.out.println(fun2());

04.        }

05.

06.        int fun2() {

07.                return 345;

08.        }

09.}

10.

11.public class B extends A {

12.        int fun2() {

13.                return 678;

14.        }

15.

16.        public static void main(String args[]) {

17.                B b = new B();

18.                b.fun1();//此处调用的fun1()方法,fun1()里面有个fun2(),这个fun2()是被子类覆盖后的fun2(),所以第一次打印678”

19.                A a = b;//此处向上转型,a是一个地址引用,绑定着new B()对象。所以执行看右边,其实是执行的b对象的继承但没有覆盖的fun1(),fun1()里面的fun2()却已经被覆盖,所以仍然是那个结果

20.                a.fun1();

21.        }

22.}

作者: 风乐    时间: 2013-5-23 23:09
class A {

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

        int fun2() {
        return 345;
    }
}

//B继承了A,首先B就有了和A一样的那些非private属性和方法
public class B extends A {

        //自己又定义一个fun2(),则把A的那个复写了
        int fun2() {         
                return 678;
        }

        public static void main(String args[]) {
                B b = new B();
                b.fun1();
               
                //这里的a的编译时类型是A,但运行时是让他指向了b指向的对象,所以运行时是和b一样的东东
                A a = b;     
                a.fun1();
        }
}
作者: 袁梦希    时间: 2013-5-23 23:40
加油~~~
作者: 赵利斌    时间: 2013-5-23 23:44
简单的一句话,多态时,编译看左边,运行看右边,
右边是一个子类对象,所以调用的都是子类的方法a.fun1()运行时,它是继承的父类的fun1()方法,可是fun1()方法又在调用fun2()方法,而此时的对象是子类对象b,所以还是调用的子类的fun2()方法  还是678
作者: xiewen    时间: 2013-5-24 00:29
就是通过继承实现多态。
A a = b;就相当于 A a =new B();
   所以  void fun1() {
                System.out.println(fun2());
        }方法里的fun2()方法是B类对象的方法。
                   黑马云青年为您解答

作者: xiewen    时间: 2013-5-24 00:47
xiewen 发表于 2013-5-24 00:29
就是通过继承实现多态。
A a = b;就相当于 A a =new B();
   所以  void fun1() {

我想说的是程序运行的时候是调用B类对象的方法,你说我那样写会产生新的对象,确实没错。
作者: 袁梦希    时间: 2013-5-24 01:32
xiewen 发表于 2013-5-24 00:29
就是通过继承实现多态。
A a = b;就相当于 A a =new B();
   所以  void fun1() {

对  这样答就行,答太少不好给分
作者: 袁梦希    时间: 2013-5-24 01:32
楼主你好,如果问题以解决,请修改分类,谢谢合作。

作者: Miss小强    时间: 2013-5-24 10:50
我觉得如果在  void fun1() {
              System.out.println(this.fun2());
      }
加个this,可能更容易理解;
不过我到现在还是不是很理解这个程序;
为什么父类中的方法内部调用的方法不是父类本身的。。
这个程序记下来。。。。。。
作者: xiewen    时间: 2013-5-24 11:05
袁梦希 发表于 2013-5-24 01:32
对  这样答就行,答太少不好给分

好,听你的
作者: 袁梦希    时间: 2013-5-24 11:10
xiewen 发表于 2013-5-24 11:05
好,听你的

嘿嘿   加油
作者: xiewen    时间: 2013-5-24 11:13
袁梦希 发表于 2013-5-24 11:10
嘿嘿   加油

呵呵......
作者: 杨彬    时间: 2013-5-24 12:20
子类继承父类重写了父类的方法  相当于你父亲开了一家公司,你继承了你父亲的公司 并且重定了以前的规定,以前规定fun2()是345  现在你规定fun2()是678,不管谁调用这个规定都会是你重订的这个了,我是这么理解的 比喻不是很恰当 楼主见谅




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