原题是这样的:
public class Test {
public static void main(String[] args) {
Zi z = new Zi();
}
}
class Fu {
int num = 5;
Fu() {
show();
System.out.println(num);
}
void show() {
System.out.println("55");
}
}
class Zi extends Fu {
int num = 3;
Zi() {
}
void show() {
System.out.println(num);
}
}
各位可以猜猜打印结果
结果是0 5,你猜对了吗???
本屌也是通过debug和问度娘之后才明白,下面就讲讲这道题
按照正常程序走,成员变量在对象创建的同时会自动复制为0,然后走构造函数,这里有一个问题,如上题子类中的 int num = 3;中的3在什么时候赋值给num,通过debug多次之后发现这个值3是在构造函数中的super()方法运行之后才会赋给num,其实父类中的构造函数可以说也隐藏了一个super()方法,因为父类上面还有一个Object类,但是那么问题来了,父类构造函数中的 show();调用的是父类中的show()方法呢还是子类中的show()方法呢?这里体现了继承的多态性,如果子类继承了父类中的方法,那么不管你在子类还是在父类中调用这个方法名,最终执行的都是子类中的方法,我是这样理解的,子类继承了父类的方法并进行了重写,那么子类中的功能就比父类中的功能要强大,那么肯定是要用子类中的方法了啊,当父类构造函数中调用show()方法的时候,其实执行的是子类中的show()方法,但是这个时候子类构造函数中的super()方法还没有执行完,那么打印的num值就是0了,最终打印出来的结果就是0 5
这里有两点是容易弄错的:
1,方法的成员变量在对象创建的时候int的默认值是0的,当你构造函数中的super()方法执行完之后才会将你的值赋给变量
2,子类复写父类的方法之后,即使你在父类中直接调用方法,最终运行的却是子类中的方法 |