锁定老帖子 主题:围观某公司的Java面试题,多态方法调用
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2014-01-06
hbthlw 写道 System.out.println(ToStringBuilder.reflectionToString(derived, ToStringStyle.DEFAULT_STYLE));
System.out.println(ToStringBuilder.reflectionToString(superr, ToStringStyle.DEFAULT_STYLE)); 输出的两个对象都是:Derived@530daa[i=20,i=10] 而且两个对象的的内存地址是一样的,说明两个变量指向的都是同一个对象。 之所以会输出10,是因为调用的都是父类中的方法,所以输出的是父类中的属性 个人愚见,希望大家讨论。 ToStringBuilder 这个东西,是哪里来的。 |
|
返回顶楼 | |
发表时间:2014-01-06
Derived derived = new Derived();
Super superr = derived; 这种方式还是常用到的。 UserDao userDao = new UserDaoImpl(),这样看就很好看了。如果父类是抽象类或者接口,子类负责具体实现。就可以这样声明。坑爹的是他的那个execute方法没写得很有欺骗性。 如果是execute(int i)的话结果就是20 把main方法放在其他类中,会发现Derived中声明的i压根就没有被使用过。 |
|
返回顶楼 | |
发表时间:2014-01-06
最后修改:2014-01-06
我培训ocjp考试认证,这样的题有一道。
这种情况确实很边缘,在开发中不太可能遇到,但是知道点总是好的,万一你遇到了,是不是就不会迷惑了? 一句话:属性静态绑定,方法动态绑定(实例方法有多态) |
|
返回顶楼 | |
发表时间:2014-01-06
hoarhoar 写道 我培训ocjp考试认证,这样的题有一道。
这种情况确实很边缘,在开发中不太可能遇到,但是知道点总是好的,万一你遇到了,是不是就不会迷惑了? 一句话:属性静态绑定,方法动态绑定(实例方法有多态) 对,就是多态。。。 |
|
返回顶楼 | |
发表时间:2014-01-06
架构师 写道 违反人类直觉,违反软件开发初衷的Java面试题。
<pre name="code" class="java"> public class Super { private int i=10; public void execute(){ System.out.println(i); } public static void main(String[] args) { Derived derived = new Derived(); Super superr = derived; System.out.println("derived value:"); derived.execute(); System.out.println("super value:"); superr.execute(); } } public class Derived extends Super { private int i=20; } </pre> 要求写出程序执行结果。 正确答案是 derived value: 10 super value: 10 但我当时写的答案是20, 20。 题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。 虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值! |
|
返回顶楼 | |
发表时间:2014-01-06
nothing.whoami 写道 架构师 写道 违反人类直觉,违反软件开发初衷的Java面试题。
<pre name="code" class="java"> public class Super { private int i=10; public void execute(){ System.out.println(i); } public static void main(String[] args) { Derived derived = new Derived(); Super superr = derived; System.out.println("derived value:"); derived.execute(); System.out.println("super value:"); superr.execute(); } } public class Derived extends Super { private int i=20; } </pre> 要求写出程序执行结果。 正确答案是 derived value: 10 super value: 10 但我当时写的答案是20, 20。 题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。 虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值! |
|
返回顶楼 | |
发表时间:2014-01-06
看了一下 thinking in java ,这种情况应该是这样的:
通过继承子类中有两个field,一个是本身的,一个是父类的,但是方法只有一个(是父类的,因为子类没有重写,如果重写了就是子类的方法) 所以调用的还是父类的方法,而父类的方法是输出父类本身的field。 如果子类重写父类方法如下: public void execute(){ System.out.println(i); } 那输出就是 derived value: 20 super value: 20 如果子类重写父类方法如下: public void execute(){ System.out.println(super.i); } 那输出就是 derived value: 10 super value: 10 有其他解释的可以再交流 |
|
返回顶楼 | |
发表时间:2014-01-06
方法动态分派,属性静态分派,http://smiky.iteye.com/admin/blogs/1767148,我这的两道题跟这很类似
|
|
返回顶楼 | |
发表时间:2014-01-07
diaozhanming 写道 nothing.whoami 写道 架构师 写道 违反人类直觉,违反软件开发初衷的Java面试题。
<pre name="code" class="java"> public class Super { private int i=10; public void execute(){ System.out.println(i); } public static void main(String[] args) { Derived derived = new Derived(); Super superr = derived; System.out.println("derived value:"); derived.execute(); System.out.println("super value:"); superr.execute(); } } public class Derived extends Super { private int i=20; } </pre> 要求写出程序执行结果。 正确答案是 derived value: 10 super value: 10 但我当时写的答案是20, 20。 题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。 虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值! 你是对的,是我想当然了! |
|
返回顶楼 | |
发表时间:2014-01-07
这道题考的是最基本的封装。实际场景就是,你在子类里定义了一个私有变量,它与父类的私有变量重名。这太常见了。这道题就是考你是否知道私有变量是绝对隔离的。如果你以为是20,20,那么在阅读代码时就无法确认一个私有变量不可能在外部(包括子类)修改。进而可以看出,你没有通过阅读代码推演程序逻辑的习惯(如果你不能确定私有变量的作用域是当前类,阅读代码进行推演的难度会很大)。
|
|
返回顶楼 | |