随笔-39  评论-376  文章-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 心梦帆影 阅读(1810) 评论(21)  编辑  收藏 所属分类: 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属性。同样还没来得及赋值。所谓的初始化,可能只是一个不成名的法则。统一一个地方来赋值,准备开工。  回复  更多评论
  

专题:iPad  jQuery  Chrome OS

博客园首页  IT新闻  闪存  学英语
标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录      
每天10分钟,轻松学英语


网站导航: