「 Java 面向对象系列 10 」
📖 上篇回顾:Java 面向对象核心入门(九):方法重写 Override|彻底分清重载与重写-CSDN博客
前面我们已经学完:继承、方法重写。
今天要学的 super 关键字,是继承体系里最容易和 this 混淆的关键字,也是 Java 面试高频基础题。
一、super 到底是什么?
super 代表:父类对象的引用 / 父类标识符。
子类中使用 super,可以访问父类的:
- 父类成员变量
- 父类成员方法
- 父类构造方法
二、super 基本使用场景
1. 访问父类成员变量
class Person {
public String name = "父类姓名";
}
class Student extends Person {
public String name = "子类姓名";
public void showName() {
System.out.println("子类姓名:" + name);
System.out.println("父类姓名:" + super.name);
}
}
测试:
public class TestSuper {
public static void main(String[] args) {
Student stu = new Student();
stu.showName();
}
}
运行结果:
子类姓名:子类姓名
父类姓名:父类姓名
✅ 结论:
- this.name:子类自己的 name
- super.name:父类的 name
2. 访问父类成员方法
子类重写父类方法后,如果还想调用父类原来的方法,可以使用 super.方法名()。
class Person {
public void say() {
System.out.println("父类:普通人说话");
}
}
class Teacher extends Person {
@Override
public void say() {
super.say(); // 调用父类方法
System.out.println("子类:老师讲课");
}
}
测试:
public class TestSuperMethod {
public static void main(String[] args) {
Teacher t = new Teacher();
t.say();
}
}
运行结果:
父类:普通人说话
子类:老师讲课
✅ 这就是 super 最常用的开发场景: 子类重写后,既保留父类逻辑,又增加子类新逻辑。
3. 访问父类构造方法
子类构造方法默认第一行有一个隐藏的 super(),表示调用父类无参构造。
class Person {
public Person() {
System.out.println("父类无参构造执行");
}
}
class Student extends Person {
public Student() {
super(); // 这一行即使不写,也会默认存在
System.out.println("子类无参构造执行");
}
}
测试:
public class TestSuperConstructor {
public static void main(String[] args) {
Student stu = new Student();
}
}
运行结果:
父类无参构造执行
子类无参构造执行
✅ 结论: 创建子类对象时,先执行父类构造,再执行子类构造。
三、super 调用父类构造方法的注意事项
1. super() 必须放在构造方法第一行
public Student() {
super(); // 必须第一行
System.out.println("子类构造");
}
2. 父类没有无参构造时,必须手动调用父类有参构造
如果父类只写了有参构造,没有无参构造,子类必须手动写 super(参数)。
class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person {
public Student(String name) {
super(name); // 必须手动调用父类有参构造
}
}
3. super() 和 this() 不能同时存在
因为它们都必须放在构造方法第一行,位置冲突,所以只能二选一。
// 错误写法
public Student() {
super();
this(); // 编译报错
}
四、this 和 super 的区别(必背)
| 代表对象 | 当前对象 | 父类对象 |
| 访问成员 | 本类成员 | 父类成员 |
| 调用构造 | this() 本类构造 | super() 父类构造 |
| 使用位置 | 本类代码中 | 子类代码中 |
五、开发中 super 的真实使用场景
场景 1:子类重写后保留父类逻辑
@Override
public void init() {
super.init(); // 先执行父类初始化
System.out.println("子类额外初始化");
}
场景 2:父类属性被覆盖,需要明确访问父类变量
System.out.println(super.name);
场景 3:父类有参构造,子类必须传参
public Student(String name) {
super(name);
}
六、常见新手坑
坑1:super() 和 this() 都想用
// ❌ 错误:两个都要求第一行,冲突
public Student() {
super();
this(); // 编译报错
}
记住:只能二选一。
坑2:父类没有无参构造,子类不手动传参
class Person {
public Person(String name) { } // 写了有参构造,无参构造失效
}
class Student extends Person {
public Student() {
// 编译报错:父类没有无参构造
}
}
解决办法:子类手动调用父类有参构造 super(name)
坑3:静态方法里写 super
public static void test() {
super.say(); // 编译报错,super 是对象相关
}
记住:super 和 this 一样,都不能在静方法中使用。
七、全文小结
🚀 下一篇预告:面向对象三大特性之 —— 多态 Polymorphism,Java 面向对象真正进入进阶核心。



