以下代码的执行结果是什么?为什么?
class Father{
public int x = 10;
Father(){
this.print();
x=20;
}
public void print(){
System.out.println("Father.x="+x);
}
}
class Son extends Father{
public int x = 30;
Son(){
this.print();
x=40;
}
public void print(){
System.out.println("Son.x="+x);
}
}
public class test {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.x);
}
}
代码分析
-
Father类的定义:
class Father{ public int x = 10; Father(){ this.print(); x = 20; } public void print(){ System.out.println("Father.x=" + x); } }
x
在Father
类中是一个实例变量,初始值为10。- 构造方法中调用了
this.print()
方法,然后将x
设置为20。
-
Son类的定义:
class Son extends Father{ public int x = 30; Son(){ this.print(); x = 40; } public void print(){ System.out.println("Son.x=" + x); } }
Son
类继承Father
类,并重新定义了实例变量x
,初始值为30。- 构造方法中调用了
this.print()
方法,然后将x
设置为40。
-
test类的main方法:
public class test { public static void main(String[] args) { Father f = new Son(); System.out.println(f.x); } }
- 创建了一个
Son
类的实例,并将其引用赋给Father
类型的变量f
。 - 打印
f.x
的值。
- 创建了一个
代码执行过程
-
创建Son对象:
- 当
new Son()
执行时,首先调用Father
类的构造方法。 Father
类的构造方法中,this.print()
实际调用的是Son
类的print()
方法,因为此时对象的实际类型是Son
。- 由于
Son
类的实例变量x
还未初始化,所以此时Son
类的x
的默认值为0,因此输出Son.x=0
。 - 然后
Father
类的构造方法继续执行,将Father
类中的x
设置为20。 - 接着,
Son
类的构造方法执行,this.print()
再次调用Son
类的print()
方法,输出Son.x=30
,因为此时Son
类的x
已经被初始化为30。 - 最后,
Son
类的构造方法将Son
类的x
设置为40。
- 当
-
打印f.x:
f
是Father
类型的引用,所以访问的是Father
类的x
,即20。- 特别要记得:
属性不存在多态性!!
输出结果
Son.x=0
Son.x=30
20