在Java中,使用super来引用父类的成分
一、基本用法
- 普通的直接引用:super 相当于是指向当前对象的父类,这样就可以用 super.xxx 来引用父类的成员。
- 子类中的成员变量或方法与父类中的成员变量或方法同名时加以区分:区分super.xxx和this.xxx。
- 引用构造函数:super(参数),Java默认在子类构造方法的第一行引用父类的构造方法。
二、super关键字测试
//测试代码
//测试类
public class TestClass {
public static void main(String[] args) {
//定义一个子类变量cc
ChildClass cc = new ChildClass();
//调用子类重写的方法
cc.method();
}
}
//父类
public class FatherClass {
//父类成员变量
public int value;
//父类成员方法,负责打印当前的value值
public void method() {
value = 10;
System.out.println("FatherClass + value: " + value);
}
}
//子类
public class ChildClass extends FatherClass{
//子类成员变量
public int value;
//子类重写的成员方法,重写了方法体
//负责打印当前的value值
public void method() {
super.method();
value = 20;
System.out.println("ChildClass + value: " + value);
System.out.println(this.value);
System.out.println(super.value);
}
}
在Java类中使用super来引用父类的成分,用this来引用当前对象,如果一个类继承了另一个类,我们在new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。
怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用。
FatherClass + value: 10
ChildClass + value: 20
20
10
三、画内存分析图,了解程序执行过程
程序都是从main方法开始执行,分析程序先从main方法的第一行代码开始。
ChildClass cc = new ChildClass();
首先,将含有main方法的字节码文件加载至方法区,从main方法的第一行开始执行。在栈区定义ChildClass类型的变量cc加,发现ChildClass的字节码未加载,则加载之。加载时发现ChildClass继承了FatherClass,则将FatherClass加载至方法区。在堆区开辟内存,创建新的ChildClass的对象。创建时调用ChildClass的构造方法,子类的无参构造方法第一行默认调用父类的无参构造方法,将内存分一部分给父类对象,并初始化父类的value=0(系统默认将int型成员变量初始化为0,但局部变量必须自己手动初始化)。 成员方法指向字节码文件中的类方法的地址。本类的初始化方法也是这样的。初始化完成后将引用地址传给变量cc。
所以,在new一个新的对象出来的时候会产生一个this引用,指向本类。如果这个类继承了其他的类,那么他的实例对象在产生后还会产生一个super引用,指向其内部父类的对象。
接下来调用cc的成员方法method。子类重写了父类的method方法, 方法体不同。第一行先通过super调用父类对象的成员方法method,为父类的value赋值,value=10,然后输出value的值。父类方法执行完后回到子类的方法内,为子类的value赋值,value=20,然后输出子类的value值。