Java 窘境
在Java继承关系中,子类会自动继承父类中定义的方法,但有时子类会对父类方法进行重写,子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。**要注意的是,父类的成员也同样会被子类的同名成员覆盖。**在调用子类中的方法时,只会调用子类重写的方法,并不会调用父类的方法。
看一段代码来理解
public class Father{
public int i = 10;
}
class Son extends Father{
// public int i = 20;
public static void main(String[] args){
System.out.printIn(new Son().i);
}
}
将子类的重写成员注释后,控制台输出10;
注释前,控制台输出20;
再看另一段代码:
package study;
public class Test{
public static void main(String[] args){
new Son();
}
}
class Father{
int i=10;
Father(){
print();
i=20;
}
void print(){
System.out.println("Father:"+i);
}
}
class Son extends Father{
public int i = 30;
public Son(){
print();
super.print();
i = 40;
}
void print(){
System.out.println("Son:" + i);
}
}
以上代码输出:
程序执行步骤如下:
不懂java加载类的过程可以看看我的上一篇博客。
Java 子类对象初始化顺序
1.加载类阶段
父类显式初始化,静态代码块
子类显式初始化,静态代码块
2.创建对象
通过new关键字为子类对象分配内存空间
父类实例成员变量初始化
父类构造方法
子类实例成员变量初始化
子类构造方法
得到子类对象
main函数中就一行语句:new Son()
首先,Son类继承了Father类,并重写了Father类的print方法。执行new Son()语句后,Java虚拟机进行加载类阶段,父类实例成员变量初始化后,执行父类的构造方法,父类构造方法中出现了print()方法,但由于子类已经重写了该方法,所以java执行子类重写后的print方法,但此时子类中的成员变量还未进行初始化,于是输出默认初始化值0。于是有了第一行的输出Son:0.
其次,执行父类构造方法中的i=20。然后进行子类实例成员变量初始化,将子类的i赋值为30,执行子类的构造方法,子类构造方法执行print()方法,于是有了控制台的第二行输出Son:30。
接着,子类构造方法执行super.print(),调用父类方法print(),控制台输出第三行:Father:20。