请JAVA高手们看看下面的代码会输出什么,并给出解释,给分,谢谢

代码如下:
package test.fatherson;

public class Father {
{
System.out.println("Static block!");
}

public Father() {
System.out.println("Father cuonstruct!");
print1();
print2();
}

public static class Son extends Father{
public Son() {
System.out.println("Son cuonstruct!");
}

public void print1(){
System.out.println("Son -> print1");
}

public void print2(){
System.out.println("Son -> print2");
}
}

public void print1(){
System.out.println("Father -> print1");
}

public void print2(){
System.out.println("Father -> print2");
}

public static void main(String[] args) {
Son s = new Son();
s.print1();
((Father)s).print2();
}
}

输出结果:
Static block!
Father cuonstruct!
Son -> print1
Son -> print2
Son cuonstruct!
Son -> print1
Son -> print2

分析过程:
这个代码块{
System.out.println("Static block!");
}
实际上是一个构造块,构造快优先于构造方法执行,而且每次实例化对象时都会执行构造块中的代码。所以你的输出的内容可以稍微改一下,如果在这段代码块前加上static又是不一样的效果,加static的代码块为静态的代码块。静态的代码块是优先于主方法执行,而且不管有多少对象,静态代码块只执行一次。
子类对象的实例化过程:
在继承的操作中,对于子类对象的实例化也是有要求的,即子类对象在实例化之前必须先调用父类中的构造方法后再调用子类自己的构造方法。所以Son s = new Son();是先执行

public Father() {
System.out.println("Father cuonstruct!");
print1();
print2();
}
再执行
public Son() {
System.out.println("Son cuonstruct!");
}
输出结果
Father cuonstruct!
Son -> print1
Son -> print2
Son cuonstruct!

s.print1();是涉及到方法的覆写,子类定义了与父类中同名的方法,方法被覆写之后,子类对象调用的方法将是被覆写后的方法。

所以输出的结果是:Son -> print1

((Father)s).print2();将子类对象强制转换成父类,调用的方法仍然是子类的方法,父类的方法已经被覆盖。就像人是动物,动物吃的是生肉,生吞活剥,但是就算你把人当动物来看,人类吃东西也不可能变成动物们那样,生吞活剥的。算人当动物,吃还是人类的吃法,不会被当动物看而回归原始状态的。
温馨提示:内容为网友见解,仅供参考
第1个回答  2013-07-18
首先,我想问下,那只是个块,你为什么要让它输出 Static block? 你也没修饰成static啊。
然后回答你问题,关于类中各个成员的初始化问题,请自己多测试总结,我给你列下
1)父类 静态方法
2)子类 静态方法
3)父类 静态块/属性(块与属性的初始化先后是根据书写顺序来定的)
4)子类 静态块/属性
5)父类 方法
6)子类 方法 /**/
7)父类 块/属性
8)父类 构造器
9)子类 块/属性
10)子类 构造器

这都是我测试测出来的。所以真实性有待观众朋友们的打击,呵呵。你也可以自己测试,举个例子,为什么方法是在构造器前初始化的? OK, 你的构造器中是可以调用本实例中的方法的,但是你不能在方法中调用本实例的构造器this();因为实例已经被实例化。其他的你自己试。

你给出的东西中,有父类块,父类构造方法,子类构造方法,所以,按上面的顺序,在你main中new Son()时,父类块先初始化,输出相应文字,再父类构造器,然后调用print1,print2,这里说一下,继承中的覆写方法具体执行哪个方法,只看实例。你new 的是Son, 所以走Son 中的print1 print2. 同样说明了你在main中的最后一句,即使强转,它的实例还是Son, 其实根本不用强转,它本身就是一种Father。 你可以在开始写的时候就写成 Father s=new Son(); 之后的内容不用我说你也懂了吧?
第2个回答  2013-07-18
Static block! //这个输出是因为你定义静态快
//实例化内部类必须先实例化它的外部类,
Father cuonstruct! //构造方法输出
Son -> print1 //构造方法输出
Son -> print2 //构造方法输出

Son cuonstruct!
Son -> print1
Son -> print2
//你强转类型了就相当与
Father s1 = new Son();
s1.print2(); 由于继承数据调用的还是自己的print2方法。
第3个回答  2013-07-18
Static block!
Father cuonstruct!
Son -> print1
Son -> print2
Son cuonstruct!
Son -> print1
Son -> print2
相似回答