继承中构造方法的关系
-
子类中所有的构造方法默认都会访问父类中空参数的构造方法
class Father{ public Father() { System.out.println("Father 的构造方法"); } } class Son extends Father { public Son() { super(); //这是一条语句,如果不写,系统会默认加上,用来访问父类中的空参构造 System.out.println("Son 的构造方法"); } }
-
父类中有有参构造方法
public class Test08 { public static void main(String[] args){ Son s1 = new Son("xiaoxin", 24); Son s2 = new Son("chenxin", 18); } } class Father { private String name; private int age; public Father(){ System.out.println("Father 空参构造"); } public Father(String name, int age){ this.name = name; this.age = age; System.out.println("Father 有参构造"); } } class Son extends Father { public Son(){ System.out.println("Son 无参构造"); } public Son(String name, int age){ System.out.println("Son 有参构造"); } }
输出结果:
在父类中定义了有参构造后,将无参构造注释掉,会报错:
将代码进行修改即可调用父类的有参构造:
class Son extends Father {
public Son(){
super("李四", 25); //因为父类的无参构造被注释了,所以这里调用父类的有参构造
System.out.println("Son 无参构造");
}
public Son(String name, int age){
super(name, age);
System.out.println("Son 有参构造");
}
}
或者:
class Son extends Father {
public Son(){
this("王五", 25); //这里调用子类的有参构造方法,子类的有参构造方法中包含了父类的有参构造,所以可行
System.out.println("Son 无参构造");
}
public Son(String name, int age){
super(name, age);
System.out.println("Son 有参构造");
}
}
super或者this,两者的使用都必须放在第一位,所以只能使用一个。
面试题
请问以下代码会输出什么?
public class Test09 {
public static void main(String[] args){
Zi zi = new Zi();
}
}
class Fu{
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu{
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
System.out.println("构造方法Zi");
}
}
1、jvm调用了main方法,main方法进栈
2、遇到了 Zi z = new Zi(),会先将Fu.class和Zi.class分别加载进内存,再创建对象,当Fu.class加载进内存,父类的静态代码块会随着Fu.class一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载。所以第一个输出“静态代码块Fu",第二个输出”静态代码块Zi"
3、走Zi类的构造方法,因为Java是分层初始化的,先初始化父类,再初始化子类,所以先走的父类构造,但是在执行父类构造时,发现父类有构造代码块,构造代码块是优于构造方法执行的,所以第三个输出构造代码块Fu,第四个输出构造方法Fu。
4、Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,第六个输出的是构造方法Zi
输出结果: