论坛首页 编程语言技术论坛

围观某公司的Java面试题,多态方法调用

浏览 16420 次
精华帖 (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 这个东西,是哪里来的。
0 请登录后投票
   发表时间:2014-01-06  
Derived derived = new Derived();
Super superr = derived; 这种方式还是常用到的。

UserDao userDao = new UserDaoImpl(),这样看就很好看了。如果父类是抽象类或者接口,子类负责具体实现。就可以这样声明。坑爹的是他的那个execute方法没写得很有欺骗性。 如果是execute(int i)的话结果就是20

把main方法放在其他类中,会发现Derived中声明的i压根就没有被使用过。
0 请登录后投票
   发表时间:2014-01-06   最后修改:2014-01-06
我培训ocjp考试认证,这样的题有一道。
这种情况确实很边缘,在开发中不太可能遇到,但是知道点总是好的,万一你遇到了,是不是就不会迷惑了?
一句话:属性静态绑定,方法动态绑定(实例方法有多态)
0 请登录后投票
   发表时间:2014-01-06  
hoarhoar 写道
我培训ocjp考试认证,这样的题有一道。
这种情况确实很边缘,在开发中不太可能遇到,但是知道点总是好的,万一你遇到了,是不是就不会迷惑了?
一句话:属性静态绑定,方法动态绑定(实例方法有多态)

对,就是多态。。。
0 请登录后投票
   发表时间: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。

题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。


虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值!
0 请登录后投票
   发表时间: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。

题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。


虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值!
即使field是public也同样打印的是父类的直,你信不信?
0 请登录后投票
   发表时间: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

有其他解释的可以再交流
0 请登录后投票
   发表时间:2014-01-06  
方法动态分派,属性静态分派,http://smiky.iteye.com/admin/blogs/1767148,我这的两道题跟这很类似
0 请登录后投票
   发表时间: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。

题目是典型的钻牛角尖。 我干嘛要声明一个子类的变量,然后又把它变成父类,又要调用父类的方法? 从来没见过这么搞的,就算实际中有,也是可读性差、可维护性差的写法,能做出这种题,只能说明是个应试型人才罢了。


虽然是继承,但是子类实例调用的方法只在父类中有,而变量又是私有的。所以调用时打印的父类中的值!
即使field是public也同样打印的是父类的直,你信不信?

你是对的,是我想当然了!
0 请登录后投票
   发表时间:2014-01-07  
这道题考的是最基本的封装。实际场景就是,你在子类里定义了一个私有变量,它与父类的私有变量重名。这太常见了。这道题就是考你是否知道私有变量是绝对隔离的。如果你以为是20,20,那么在阅读代码时就无法确认一个私有变量不可能在外部(包括子类)修改。进而可以看出,你没有通过阅读代码推演程序逻辑的习惯(如果你不能确定私有变量的作用域是当前类,阅读代码进行推演的难度会很大)。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics