子类对象的初试化:一定是先初始化父类中定义的成员变量的值,再初始化子类中定义的成员变量的值
有两种方法可以让父类的构造方法先于子类构造方法:
1、子类对象的隐式初始化
2、子类对象的显式初始化
隐式初始化:当父类提供了默认的构造方法,且父类的构造函数中没有显式调用父类的其他构造方法,则在执行子类的构造方法之前会自动执行父类的构造方法,直到执行完object的构造函数后才执行子类的构造方法。
public class Demo1ImplicitInit {
public static void main(String[] args) {
ImplicitSon implicitSon = new ImplicitSon(10);
}
}
class ImplicitFather {
int fatherI;
//public ImplicitFather() {
// fatherI = 103;
// System.out.println("这是父类的构造方法");
//}
//
//public ImplicitFather(int fatherI) {
// System.out.println("这是父类的构造方法ImplicitFather(int fatherI)");
// this.fatherI = fatherI;
//}
}
class ImplicitSon extends ImplicitFather {
int i;
public ImplicitSon(int i) {
// 子类构造方法的第一条语句的位置,调用一下
System.out.println("这是子类的构造方法");
this.i = i;
}
}
显式初始化:我们自己通过某种方式,调用父类的有参构造方法,要求我们在子类构造方法执行之前调用父类的构造方法。(因为子类对象的初始化一定要求先父类成员变量初始化,在子类成员变量初始化)
super关键字:super代表父类对象的内存空间的标识。this代表当前这个对象,这个对象的内存空间标识。
用法:
访问成员变量
this.成员变量 super.成员变量
访问构造方法
this(...) super(...)
访问成员方法
this.成员方法() super.成员方法()
有了super关键字,我们就可以在子类构造方法的第一条语句通过super()调用父类的默认构造方法。
public class Demo2ExplicitInit {
public static void main(String[] args) {
ExplicitSon explicitSon = new ExplicitSon();
System.out.println(explicitSon.fatherI);
}
}
class ExplicitFather {
int fatherI;
//public ExplicitFather() {
// System.out.println("default constructor");
//}
public ExplicitFather(int fatherI) {
System.out.println("ExplicitFather(int fatherI)");
this.fatherI = fatherI;
}
}
class ExplicitSon extends ExplicitFather {
int sonI;
public ExplicitSon() {
super(9);
//this();// 这里会报一个错 递归错误
}
public ExplicitSon(int sonI) {
// 子类对象的显示初始化
super(1000); //调用了父类汇中定义的一参都早方法
//super(); //通过super调用到父类的无参构造方法
System.out.println("ExplicitSon(int sonI)");
this.sonI = sonI;
}
}
父类域的隐藏问题:如果说父类中定义了和子类同名的成员变量,此时在子类类体重,如果直接通过变量名去访问成员变量的值,只能访问到子类中定义的成员变量,就好像父类中同名的成员变量, 被子类中同名成员变量给隐藏掉了。
public class Demo1 {
public static void main(String[] args) {
FieldSon fieldSon = new FieldSon();
//fieldSon.printSonField(); // 200 说明
//fieldSon.printFatherField();
fieldSon.printAll();
}
}
class FieldFather {
int i = 1;
int j = 1000;
public void printFatherField() {
System.out.println(i);
}
}
class FieldSon extends FieldFather {
int i = 200;
public void printSonField() {
System.out.println(i);
}
public void printAll() {
//System.out.println(i); //直接通过同名变量的变量名访问子类的同名成员变量值
//
通过super关键字,就指明了访问的是父类成员变量中定义的同名成员变量的值
//System.out.println(super.i);
System.out.println(j);
}
}