class Father
{
int age = 20;
Father()
{
say();
System.out.println(age);
}
void say()
{
System.out.println(age);
}
}
class Child extends Father
{
int age = 40;
Child(){
say();}
void say()
{
System.out.println(age);
}
public static void main(String[] args)
{
new Child();
}
}
{
int age = 20;
Father()
{
say();
System.out.println(age);
}
void say()
{
System.out.println(age);
}
}
class Child extends Father
{
int age = 40;
Child(){
say();}
void say()
{
System.out.println(age);
}
public static void main(String[] args)
{
new Child();
}
}
一样的帖
0
20
40
考的是父类和子类初始化顺序的问题。基类参数->基类构造器->子类参数->子类构造器(未考虑静态字段以及静态块,实际是一样的)。
Child子类构造函数中首先调用父类Father 的构造函数,遇见了say()方法,这个方法是缺省的方法故而可以看成类接口的一部分可以动态转型,从而调用Child的方法。然后这个时候Child的age没有初始化(基类还没有构造完全),故而打印0,后面当然打印自身的age为20,然后最后调用Child的打印age为40.
我在另外一个帖子已经回了
class Father
{
int age = 20; //4,初始化age
Father() //3,初始化Child的基类
{
say(); //5,调用Child的say()
System.out.println(age); //7,输出20
}
void say()
{
System.out.println(age);
}
}
class Child extends Father
{
int age = 40; //8,初始化Child中的age
Child() //2,构造Child对象
{
say();//9,调用Child的say()
}
void say()
{
System.out.println(age); //6,第一次age=0,输出0//10,第二次age=40,输出40
}
public static void main(String[] args)
{
new Child(); //1,主程序入口
}
}
http://blog.csdn.net/KingWolfOfSky/archive/2009/08/13/4444231.aspx
你看看《Thinking is Java》继承那一章的几个例子,可以帮助你理解。