随笔-42  评论-578  文章-1  trackbacks-0
用这题目吸引大家注意,请见谅!
以下代码有些朋友可能会似曾熟识,可能也算不上“原创”,请见谅!
不过,我出的这题,确定有点意思,考考大家。
/**
 * 父类
 * 
@author rongxinhua
 *
 
*/
public class Father{
    
private String name="FATHER";
    
public Father(){
        whoAmI();
        tellName(name);
    }
    
public void whoAmI(){
        System.out.println(
"Father says, I am " + name);
    }
    
public void tellName(String name){
        System.out.println(
"Father's name is " + name);
    }
}

/**
 * 子类
 * 
@author rongxinhua
 *
 
*/
public class Son extends Father{
    
private String name="SON";
    
public Son(){
        whoAmI();
        tellName(name);
    }
    
public void whoAmI(){
        System.out.println(
"Son says, I am " + name);
    }
    
public void tellName(String name){
        System.out.println(
"Son's name is " + name);
    }
}

问题:当执行 Father who = new Son(); 时,会输出什么?
如果你去参加一个公司的笔试或面试时问了这么一道题,在没有环境测试的情况下,你会猜测什么答案?



本文原创,转载请注明出处,谢谢!http://www.blogjava.net/rongxh7(心梦帆影JavaEE技术博客)
    

posted on 2009-11-28 03:21 心梦帆影 阅读(4034) 评论(24)  编辑  收藏 所属分类: JavaSE

评论:
# re: 原创一道Java笔试面试题考考大家 2009-11-28 09:10 | 凌晨风
我觉得应该这样理解:
1. 由于先有父类后有子类,所以生成子类之前要首先有父类。但是有继承,当你试图产生一个子类的实例时,首先要执行子类的构造函数,但是由于子类继承父类,所以子类的构造函数自动调用父类的构造函数。先产生父类的实例,然后再产生子类的实例。
2. 初始化问题,java虚拟机初始化构造函数可以,变量也可以,当你new son()时, whoAmI();首先调用Father初始化,但是String类型变量初始化有一个前提,第一次使用的时候才初始化,此时 whoAmI();方法的name应该为null,其后可以正常解释了。
3. new Son() 就可以测试了,没必要Father who = new Son(); 写这个,因为你不曾体现到继承后的多态,反而造成误解,不过作为测试题目倒是挺扰人的。
一家之言,不知对不对,希望大家给个正解
  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 09:16 | bigruan
对运行结果不是很理解,博主能解释下吗?  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 10:05 | hantuo
我的答案:

Father says, I am FATHER
Father's name is FATHER
Son says, I am SON
Son's name is SON  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 10:32 | hbdrawn
一楼的解释关于null值得出现是不是不正确呢?  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 10:33 | hbdrawn
正解:
Son says, I am null
Son's name is FATHER
Son says, I am SON
Son's name is SON  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 10:37 | fds
都是son的内容。java和c#不一样。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 11:16 | feenn
这个题目其实是一个小Trick,要注意whoAmI和tellName函数的区别:一个是打印field的值,而另一个是打印参数。
其实过程是这样的:
1.创建Son的时候先创建Father,而Father中的whoAmI是已经被Son覆盖了,因此这里打印的name这个field是Son中的field,而此时还没有构造Son,因此Son中的name的值是null(这里即使是写了String name = "SON"也是没有用的,因为父类没有构造结束之前,这里是不会被执行的)。
2.Father在执行tellName的时候,传递的参数name是Father自身的name这个field值,这个值是已经被赋值为"FATHER"的,因此会打印出“Son's name is FATHER”
3.Father构造完毕后开始构造Son,这里的打印结果就可以按照常规方式来解释了。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 11:35 | Never
Son's name:null
Som says: my name is:null
Son's name:Son
Som says: my name is:Son
运行了下,但还是不太明白  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 12:08 | Leonfisher
Son says, I am null
Son's name is FATHER
Son says, I am SON
Son's name is SON

后面两项输出应该都能理解,主要是前面两项,分享一下我的理解:
new Son() 时,首先初始调用父类的<init>方法(这是必然的,既使没有继承任何类的类也会调用 Object 的<init>方法),这样就执行到 Father 类的 <init> 方法,首先是成员变量的初始化,private String name="FATHER",然后执行 whoAmI(),因为 Son overwrite 了这个方法,所以实际执行 Son 的 whoAmI() 方法,Son 的 whoAmI() 方法中使用了 name 变量,这里用的实际是 Son 的 name 变量,这个时候还没有初始化,所以是 null ,这就是第一行输出;然后是 tellName(name),当然也是执行的 Son 的 tellName(name) 方法,不同的是传了参数 name 进来,这个 name 是 Father 里的 name ,值是 "FATHER",于是就是第二行输出。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 13:47 | xzqttt
@feenn
正解  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 15:08 | nathen
public class Son {

private String userName = "test";

Son() {
whoAmI();
sayMyName(this.userName);

}

public void whoAmI() {
System.out.println("Hell everyone i'm" + userName);
}

public void sayMyName(String username) {
System.out.println("Hell world!!!my name is " + userName);
}

public static void main(String args[]) {
Son son = new Son();
}
}

帮忙解释下,为什么上面的代码的结果是
Hell everyone i'mtest
Hell world!!!my name is test
而不是
Hell everyone i'm null  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 15:11 | nathen
没搞明白,因为按照大家说的,
. 初始化问题,java虚拟机初始化构造函数可以,变量也可以,当你new son()时, whoAmI();首先调用Father初始化,但是String类型变量初始化有一个前提,第一次使用的时候才初始化,此时 whoAmI();方法的name应该为null,
可为什么我上面的例子可以把值给打出来呢?  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-28 21:41 | bzp
挺有趣,我同意 @feenn  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家[未登录] 2009-11-29 10:40 | john
关键:父类的引用指向之类对象的问题  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-30 09:16 | mathfox
这个有意思,

我都回答错了,唉,还要努力。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-11-30 10:22 | 凌晨风
@Leonfisher
正解  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-12-01 12:39 | Gua_Hu
@凌晨风
但是String类型变量初始化有一个前提,第一次使用的时候才初始化.
-----
不是这样吧?


@feenn
正解
  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-12-02 13:52 | jl6250
@nathen
你的Class Son()是没有继承Father(),所以根据JAVA Class的初始化顺序,应该先初始化成员变量,然后再执行构造函数,所以打印出来的结果会是
Hell everyone i'mtest
Hell world!!!my name is test 。
  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家[未登录] 2009-12-05 12:46 | rabbit
用eclipse调试一下,就可以发现,方法都是调用Son的方法,所有会出现第一次为null
第二次方法调用很值得我们深思啊,他告诉了我们调用父类隐藏字段的方法  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-12-06 22:54 | 凌晨风
我也是一家之言,执行父类的构造函数时因为子类重写了此方法,而此时Son的name还没有构造出来。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2009-12-08 23:22 | ynyee
这种写法只是一种语法,并不能用我们看到的语法加上老师告诉我们的理论来确定这件事情,我倒觉得是这是一种编写代码的语法,真正在执行的时候,可能我们所做的String name="Father" 这种操作,不是一下就完成的,大致上应该是先将指针指向NULL,再创建Father字符串,再把指针指向这个字符串,在赋值这个阶段,使用的是子类的实例所以调用的是自身的方法,输出的name是NULL,这时候输出的按理来说是子类的name属性。同样还没来得及赋值。所谓的初始化,可能只是一个不成名的法则。统一一个地方来赋值,准备开工。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2010-04-23 22:09 | ren
正确答案
Son says, I am null
Son's name is FATHER
Son says, I am SON
Son's name is SON  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2011-03-28 00:13 | Duke
说下俺的理解,菜鸟一个大家别喷
首先由于SON继承了FATHER,所以也同样继承了父类的所有方法,但是因为方法同名,所以子类方法覆盖了父类的方法。但是由于是通过SON类来实例,所以肯定要先实例化父类,直接进去父类的无参数构造方法,此时name并没有值是null,所以whoAmI()方法产生了Son says, I am null,接着执行tellName(name),此时FATHER会去寻找name的值,此刻name被赋值为FATHER,产生了Son's name is FATHER;执行晚会来SON类里面按照由上到下的顺序产生了后面2句Son says, I am SON;Son's name is SON;
运行正确答案:
Son says, I am null
Son's name is FATHER
Son says, I am SON
Son's name is SON

如果父类FATHER中声明变量private static String name="FATHER";
在非机器运行你能猜出结果是什么样子的嘛?答案由你来揭晓。  回复  更多评论
  
# re: 原创一道Java笔试面试题考考大家 2013-04-16 16:54 | 王智钟
@hbdrawn
父类的private String name="FATHER";的变量时不继承给子类的,是private类型。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: