黑马程序员技术交流社区

标题: 刚刚视频面试,美女老师出了个很棘手的问题 [打印本页]

作者: Seraphim    时间: 2014-5-23 19:01
标题: 刚刚视频面试,美女老师出了个很棘手的问题
本帖最后由 Seraphim 于 2014-5-23 21:46 编辑

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();
                }
        }

这段代码的运行结果及解释……我确实蒙圈了,有大神解释下么
作者: 官珺伟    时间: 2014-5-23 19:58

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();  // 打印fun2()的结果:456 (B覆盖了A的方法)
            A a = b;   //new B()赋值给a
            a.fun1();  // new B().fun1()的结果:456
    }
}


作者: 邵镛    时间: 2014-5-23 20:07
执行结果都是456.
这段代码表示:类B 继承 类A

第一个结果:
B b = new B(); 这里new了一个B类的对象b
b.fun1();          对象b调用了父类(A)的方法fun1(),就会执行fun1()的代码
void fun1() {
        System.out.println(fun2());
}
                      会执行fun2()的函数。然而B类覆盖了A类的fun2()方法。所以会执行B类的fun2()方法。即456.

第二个结果:
A a = b;   a.fun1();
       创建了父类A的一个对象a,指向子类B的对象b。
       此时调用 a.fun1(); 即也会调用子类覆盖了父类的fun2()方法,结果任是456.

不知我的解释是否正确,还请验证
作者: Dark_Horse    时间: 2014-5-23 20:08
运行结果应该是456,456
因为B类继承A类,B类会把A类的方法继承过来,只是在B类中并没有显示出来,执行b.fun1()方法时,调用了fun()2方法,这时候B类重写了该方法,所以会去执行子类的fun2()方法。
第二个输出的也是456,因为A a= b;程序在编译期是看做A类型的,但是在运行期是看做B类型的,在调用a.fun()1方法时,其实是调用子类的fun1()方法,这时调用了fun2()方法,子类重写了该方法,所以输出为456....
以上只是个人分析,本人菜鸟刚学java.....其他大神们是怎么分析的呢?
作者: AntThinking_toT    时间: 2014-5-23 20:14
1.结果:
        456
        456
2.考点:
       ①类继承;②方法调用与重写;③引用赋值及父类子类之间赋值的关系,内存图。
3.解析:
       父类A定义两个方法,fun1和fun2,其中fun1调用fun2,fun1应该输出123(只看父类时);
       子类B覆盖(override)父类方法fun2返回值456(注意:当子类覆盖父类方法时,new出的子类对象调用fun2时应该调用其覆盖的方法,而不是其父类方法,这是理解此题的关键)。
       B类main函数,new出b对象,其调用其子身fun1,结果为456,这个好明白;接着又创建父类A的引用变量a,然后把子类B的对象引用赋值给a(子类可以赋值给父类,但是父类不可赋值给子类变量,如:苹果可以叫水果,但是水果不能叫苹果,因为水果并不一定指苹果,也可能指香蕉或其它),也就是说a最终调用的还是b,所以输出的结果还是456。
       顺便问一下LZ,报的Android还是JavaEE+云,多少期的?

作者: 酱油炒饭    时间: 2014-5-23 21:35
长知识啊长知识~
作者: Seraphim    时间: 2014-5-23 21:44
AntThinking_toT 发表于 2014-5-23 20:14
1.结果:
        456
        456

报的云10,你呢
作者: Seraphim    时间: 2014-5-23 21:46
谢谢楼上各位了~现在明白了,美女老师面试的很全面,大家准备面试的时候一定要认真~
作者: More    时间: 2014-5-23 21:54
属性是静态绑定的,方法是动态绑定, B b = new B();创建出B的实例  b.fun1(); 继承了类A的fun1(),因为方法是动态绑定的  所以b.fun1()调用的是类B中的fun2() // 打印fun2()的结果:456 (B覆盖了A的方法)
A a = b;   //new B()赋值给a,返回的仍是456,这里调用的还是类B中的fun2().
           
         
作者: iloveyou    时间: 2014-5-23 22:16
加油加油
作者: 凌羽猎风    时间: 2014-5-23 22:22
楼上的解释很好了  为什么我总是做错  一看还都能看得明白……果然还是不够熟练……
作者: AntThinking_toT    时间: 2014-5-23 22:26
Seraphim 发表于 2014-5-23 21:44
报的云10,你呢

我准备报云11,学长啊。面试整个过程大概是什么样的,老师会问些什么问题?
作者: jsjchenlong    时间: 2014-5-23 23:10
我在你之前的代码上加了一些测试代码,是为个你给更好的解释,注意看我的注释。我的答案可能会和上面几位哥们说的不一样,理解起来肯能也有些抽象。
class A {
    void fun1() {
            /**注意你的这段代码你之前是没有this的,但是你要知道,其实这里的this是隐藏了
             * 你要知道这个this是代表对象的地址(就是调用者对象的地址),说白了就是谁调用我,
             * 我就执行谁的方法.所以和覆盖没有关系。
             *
             */
          System.out.println(this.fun2());
          //这是个测试为了证明上面说的
          System.out.println(this);//Test.B@150bd4d
    }

    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();//456
           System.out.println(b.fun2());//456
           //为了证明b对象的地址和A类中的fun1()方法里隐藏的this地址是一样的
           System.out.println(b);//Test.B@150bd4d
           //这里是多态(多态里的对象调用的方法是子类父类共有的方法,并且这个方法是调用子类重写父类的方法)
            A a = b;
            a.fun1();//456
            System.out.println(a.fun2());//456
          //为了证明a对象的地址和A类中的fun1()方法里隐藏的this地址是一样的
            System.out.println(a);//Test.B@150bd4d
    }
}

作者: jsjchenlong    时间: 2014-5-23 23:15
有笔试题吗?有几道笔试题?都是什么啊?面试你的是那个老师?
作者: 神秘梦    时间: 2014-5-23 23:38
继承的知识,运行结果应给是456
作者: hamiguadjs    时间: 2014-5-24 01:16
面试题考察的很基础啊,感觉自己的希望又增大了。
作者: 帅哥哥    时间: 2014-5-24 01:45
我擦,这是我基础测试的题……
作者: Seraphim    时间: 2014-5-24 17:22
jsjchenlong 发表于 2014-5-23 23:15
有笔试题吗?有几道笔试题?都是什么啊?面试你的是那个老师?

有道题让我写个程序,找出数组中的最小值。。。。这个应该很简单吧,别的都是视频里的东西,大家认真看就好
作者: 假Rǔ有⒈兲    时间: 2014-5-24 18:28
看了下解答
作者: 飘渺≮★耘    时间: 2014-5-24 20:23
结果是456  456  b访问fun()1 ,fun1()调用腐女
作者: 飘渺≮★耘    时间: 2014-5-24 20:27
上面回复纯属意外
结果是456  456  b访问fun()1 ,fun1()调用fun2(),而fun2()被b覆盖
作者: 不羁的风1230    时间: 2014-5-24 21:02
B是A的子类它会继承父类的所有非私有成员,其中fun1()、fun2(),都被继承了,B b = new B();是创建了一个B
作者: 不羁的风1230    时间: 2014-5-24 21:05
不羁的风1230 发表于 2014-5-24 21:02
B是A的子类它会继承父类的所有非私有成员,其中fun1()、fun2(),都被继承了,B b = new B();是创建了一个B ...

继续,b调用继承A的fun1,然后fun1调用B中重写的A中的fun2方法,所以输出的是456,后边是将b的地址赋给a,然后第二次所以输出的也是456
作者: 寻找人生目标    时间: 2014-5-24 22:29
额 哥们  还出什么题了   大致的给说下   谢谢  
作者: 大bao    时间: 2014-5-25 00:14
原来我也做对了
作者: 贾俊锋    时间: 2014-5-25 01:21
确实挺绕,学习了,
作者: wuhyoung    时间: 2014-5-25 10:34
结果都是456,方法是必须要覆盖的,除了方法别的是不能覆盖的,记住这一点就行了
作者: 茂子    时间: 2014-5-26 09:30
AntThinking_toT 发表于 2014-5-23 20:14
1.结果:
        456
        456

学习了,,,
作者: 伪猫君    时间: 2014-10-6 19:10
都是456,不是很难吧




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