super关键字用于子类显式访问父类的成员变量、构造方法和被重写的方法;必须在非静态方法中使用;可访问public/protected/包内可见成员,但不能访问private成员。

super 关键字用于在子类中显式访问父类的成员变量、构造方法和被重写(override)的方法。它不是“强制调用”的开关,而是一种明确指定调用目标的语法手段——尤其在子类覆盖了父类方法或隐藏了父类字段时,用 super 才能绕过子类的定义,直接访问父类版本。
调用父类被重写的方法
当子类重写了父类的实例方法(如 toString()、equals() 等),若想在子类方法内部复用父类逻辑,就需用 super.方法名()。
- 必须在非静态方法中使用(super 不能出现在 static 上下文)
- 常用于“扩展而非替换”场景:先执行父类逻辑,再添加子类特有行为
- 例如:
class Animal {
public String getInfo() { return "Animal"; }
}
class Dog extends Animal {
@Override
public String getInfo() {
return super.getInfo() + " and Dog"; // 输出 "Animal and Dog"
}
}
访问被子类同名字段隐藏的父类成员变量
如果子类定义了与父类同名的实例变量(非方法),该变量会隐藏(not override)父类字段。此时用 super.字段名 可明确访问父类版本。
- 注意:字段不具有多态性,访问哪个字段取决于引用类型(编译期决定),而非对象实际类型
- super.field 是唯一能避开子类字段、拿到父类字段值的方式(前提是字段可访问)
- 例如:
class Parent { int x = 10; }
class Child extends Parent {
int x = 20;
void printX() {
System.out.println(x); // 输出 20(子类字段)
System.out.println(super.x); // 输出 10(父类字段)
}
}
在子类构造器中调用父类构造器
每个子类构造器默认第一行隐含 super()(无参调用)。若父类没有无参构造器,或你想传参调用特定父类构造器,就必须显式写出 super(...),且必须是构造器中的第一句。
- 不能和 this(...) 同时出现(二者都必须是首句)
- 若父类只有带参构造器,子类构造器必须显式调用 super(…),否则编译失败
- 例如:
class Vehicle {
Vehicle(String brand) { System.out.println("Brand: " + brand); }
}
class Car extends Vehicle {
Car(String brand, String model) {
super(brand); // 必须写,且必须第一行
System.out.println("Model: " + model);
}
}
不能用 super 访问 private 成员
super 只能访问父类中对子类可见的成员:即 public、protected,以及默认访问权限(同一包内)的字段和方法。
- 父类的 private 成员对子类不可见,super.privateField 或 super.privateMethod() 会编译报错
- 若需间接访问,父类应提供 protected/public 的 getter 或模板方法











