目录

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(...),调用父类构造方法

参考资料