1. 简介

本文深入讲解 Java 中的 super 关键字。

super 的核心作用是访问父类成员 —— 包括构造器、变量和方法。这是继承机制中非常关键的一环,尤其在处理类的层次结构时,掌握 super 的用法能避免不少“踩坑”。

我们接下来从构造器、成员变量、方法重写三个维度,逐一剖析 super 的实际应用场景。


2. super 与构造器

在子类构造器中,可以通过 super() 调用父类的构造方法。⚠️ 必须放在构造器的第一行,否则编译报错。

比如,我们有一个父类:

public class SuperBase {
    String message;

    public SuperBase(String message) {
        this.message = message;
    }
}

子类通过 super(message) 显式调用父类带参构造器:

public class SuperSub extends SuperBase {

    public SuperSub(String message) {
        super(message); // 调用父类构造器
    }
}

当我们实例化子类时:

SuperSub child = new SuperSub("message from the child class");

执行流程如下:

  1. new SuperSub(...) 触发子类构造器
  2. 子类构造器第一行执行 super(message),跳转到父类构造器
  3. 父类完成初始化后,再回到子类继续执行

📌 注意:如果你没写 super(),编译器会自动插入 super() 调用父类无参构造器 —— 所以父类必须有无参构造器,否则报错。


3. 访问父类成员变量

当子类和父类存在同名成员变量时,子类会“遮蔽”(shadow)父类的变量。此时想访问父类的原始变量,就必须使用 super

定义父类:

public class SuperBase {
    String message = "super class";

    public SuperBase(String message) {
        this.message = message;
    }
}

子类定义了同名变量:

public class SuperSub extends SuperBase {

    String message = "child class";

    public void getParentMessage() {
        System.out.println(super.message); // 显式访问父类变量
    }

    public void getChildMessage() {
        System.out.println(this.message);
    }
}

调用示例:

SuperSub child = new SuperSub("custom message");
child.getParentMessage(); // 输出: custom message(因为构造器已修改父类 message)
child.getChildMessage();  // 输出: child class

关键点super.message 指向的是父类中的 message,即使它被子类同名变量遮蔽。


4. super 与方法重写

当子类重写了父类方法后,如果仍想调用原始的父类实现,就可以用 super.methodName()

先看父类定义:

public class SuperBase {
    String message = "super class";

    public void printMessage() {
        System.out.println(message);
    }
}

子类重写 printMessage(),并在构造器中同时调用父类和子类版本:

public class SuperSub extends SuperBase {

    String message = "child class";

    public SuperSub() {
        super.printMessage(); // 调用父类方法
        printMessage();       // 调用子类重写后的方法
    }

    @Override
    public void printMessage() {
        System.out.println(message);
    }
}

输出结果:

super class
child class

典型应用场景

  • 在子类构造器中初始化前先调用父类逻辑
  • 子类增强父类方法(如日志、校验)后,再调用 super.method() 执行原逻辑

⚠️ 注意:super 调用的是直接父类的方法,不会动态绑定到更上层,所以它是“静态”的调用。


5. 总结

super 是 Java 继承体系中的核心关键字,主要用途包括:

  • ✅ 在子类构造器中调用父类构造器(必须第一行)
  • ✅ 访问被子类遮蔽的父类成员变量
  • ✅ 调用被重写的父类方法,实现逻辑复用或增强

📌 常见踩坑点

  • 忘记父类无参构造器导致子类编译失败
  • 在静态上下文中误用 super
  • 误以为 super.method() 会动态绑定 —— 实际是静态绑定到父类

完整示例代码已托管至 GitHub:
👉 https://github.com/javaguide/tutorials/tree/master/core-java/core-java-oop-inheritance


原始标题:Guide to the super Java Keyword