Java 基础-super 关键字
super 是什么
super用于从子类访问直接父类的成员或调用父类构造方法。常见用法有三个:访问父类中被遮蔽的字段、调用父类中被重写的方法、调用父类构造方法。
访问父类字段
字段不存在重写。子类声明同名字段时,只是遮蔽了父类字段。在子类中可以用
super.field访问父类中的那一份数据。
class Vehicle {
int maxSpeed = 120;
}
class Car extends Vehicle {
int maxSpeed = 180;
void printSpeed() {
System.out.println(maxSpeed); // 180
System.out.println(super.maxSpeed); // 120
}
}
字段访问根据引用的编译期类型确定,不具有方法重写那样的动态绑定。
调用父类方法
子类重写父类方法后,普通调用会执行子类实现。如果重写方法需要复用父类逻辑,可以使用
super.method()。
class Person {
void introduce() {
System.out.println("Person");
}
}
class Student extends Person {
@Override
void introduce() {
super.introduce();
System.out.println("Student");
}
}
super.method()只绕过当前这一次动态分派。如果父类方法内部又普通调用了另一个被重写的方法,那个调用仍然会动态分派到子类。
调用父类构造方法
创建子类对象时,必须先完成父类部分的初始化。
super(...)用于显式调用直接父类构造方法。
class Person {
private final String name;
Person(String name) {
this.name = name;
}
}
class Student extends Person {
Student(String name) {
super(name);
}
}
如果构造方法没有显式调用
this(...)或super(...),编译器会隐式调用super()。因此,父类没有可访问的无参构造方法时,子类必须显式调用父类的其他构造方法。
[!yellow]
Java 24 及之前,super(...)必须是构造方法的第一条语句。Java 25 开始允许在它之前执行不访问当前对象的语句。面试时应先确认 Java 版本。
super 面试考点
super只能用在子类的实例上下文中,不能在static方法或静态代码块中使用。- 字段是遮蔽,方法才可以重写;字段访问是静态绑定,重写的实例方法是动态绑定。
super.method()调用直接父类中的实现,常用于“父类逻辑 + 子类扩展”。super(...)调用直接父类构造方法;它和this(...)都是显式构造方法调用,一个构造方法中最多出现一个。- 构造方法不会被继承,因此不能被重写,但可以重载。
this 与 super 的区别
| 对比项 | this |
super |
|---|---|---|
| 表示对象 | 当前对象 | 当前对象的父类部分 |
| 访问成员 | 当前类的实例字段和方法 | 父类中被遮蔽的字段或被重写的方法 |
| 构造调用 |
this(...),调用本类其他构方法 |
super(...),调用父类构造方法 |