问题:
父类构造函数带有参数:
public Employee(int a ){}
子类要在构造函数中输入参数:
int a =1;
SE(){super(a);}
结果出错:
Cannot refer to an instance field arg while explicitly invoking a constructor(在明确调用一个构造器的时候不能引用类的一个实例域)
eclipse提示要将a变量加上static修饰符。
为什么成员变量就不行呢?
百度的解释
原因很简单,我们假如可以通过编译器。我问一个问题,调用构造器是干什么的?
大家都知道,创建一个对象并初始化对象中的数据域。红色字体很重要,在上面的列子中new MyThing()的作用就是为了初始化这个对象的数据域i,试问在没有通过构造器初始化之前,i的值是不确定的。我们怎么能使用一个不确定的i值来初始化对象。
必须要先明确初始化实例域,才能创建好对象,进而才能使用对象的数据域。在没有实例化之前就想使用他,不可能。
好像有点道理,但是又有了一个问题:
成员变量初始化是在执行构造函数之前,为什么已经int a =1了,super(a)中的a却没有确定的值?
答案:super()的调用先于成员变量初始化
经过断点调试后我发现了super()是在成员变量初始化之前执行的,所以执行时a还没有初始化。
执行过程
测试类,创建子类对象
public class Test {
public static void main(String[] args) {
SE se = new SE(5);
}
}
子类
public class SE extends Employee{
static String[] a = {"呵呵"};
int b =4;
static {
System.out.println("子类静态代码块");
}
SE(){
super(5);
System.out.println("子类构造函数无参数");
}
SE(int a){
this();
System.out.println("子类构造函数");
}
}
父类
public class Employee {
static int id = 1;
int abc =50;
public Employee() {
super();
System.out.println("父类构造函数无参数");
}
public Employee(int a ) {
this();
System.out.println("父类构造函数带参数");
}
static {
System.out.println("父类静态代码块");
}
}
开始执行:
1.加载SE的class文件
SE se = new SE(5);
2.直接进入父类初始化static类变量、static静态代码块
static int id = 1;
static {System.out.println("父类静态代码块");}
3.进入子类初始化类变量、静态代码块
static String[] a = {"呵呵"};
static {System.out.println("子类静态代码块");}
4.执行子类有参构造函数的this();
5.执行子类无参构造函数的super(5);
6.执行父类有参构造函数的this();
7.执行父类无参构造函数的super();
8.初始化父类的成员变量
int abc =50;
9.执行父类无参构造参数中的语句
System.out.println("父类构造函数无参数");
10.执行父类有参构造函数中的语句
System.out.println("父类构造函数带参数");
11.初始化子类的成员变量
12.执行子类无参构造参数中的语句
13.执行子类有参构造函数中的语句
结束。
总结
简单的来说就是
1.父类static模块
2.子类static模块
3.父类this()和super()
4.子类this()和super()
5.父类初始化成员变量,无参构造,有参构造
6.父类初始化成员变量,无参构造,有参构造