sidebar: 'heading'
super
在 Java 中,super 关键字用于引用父类(超类)的成员(方法、变量或构造函数)。它在继承关系中扮演重要角色,下面详细解释其用法和作用:
1. 访问父类的成员变量和方法
当子类与父类存在同名成员时,super 可用于显式引用父类的成员。
class Animal {
protected String name = "动物";
public void eat() {
System.out.println("动物进食");
}
}
class Dog extends Animal {
private String name = "狗狗";
public void printInfo() {
System.out.println(super.name); // 访问父类的 name: "动物"
System.out.println(this.name); // 访问子类的 name: "狗狗"
super.eat(); // 调用父类的 eat() 方法
}
}
2. 调用父类的构造函数
在子类的构造函数中,super() 用于调用父类的构造函数,必须放在第一行。
class Person {
protected String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person {
private int studentId;
public Student(String name, int studentId) {
super(name); // 调用父类的构造函数
this.studentId = studentId;
}
}
注意:
- 如果子类构造函数中不显式调用
super(),编译器会自动添加无参的super()。 - 如果父类没有无参构造函数,子类必须显式调用父类的有参构造函数。
3. 子类重写方法中调用父类的实现
当子类重写父类的方法时,可以使用 super 调用父类的原始方法实现。
class Shape {
public void draw() {
System.out.println("绘制形状");
}
}
class Circle extends Shape {
@Override
public void draw() {
super.draw(); // 调用父类的 draw() 方法
System.out.println("绘制圆形");
}
}
4. 在内部类中引用外部类的父类成员
多层继承时,若需跳过直接父类,引用更上层父类的成员,可使用 super.super(语法不支持,但可通过中间类间接实现)。
class Grandparent {
public void display() {
System.out.println("祖父母");
}
}
class Parent extends Grandparent {
@Override
public void display() {
System.out.println("父母");
}
}
class Child extends Parent {
@Override
public void display() {
// 无法直接使用 super.super.display()
// 但可通过调用父类的方法间接实现
super.display(); // 调用 Parent 的 display()
}
}
5. 访问父类的静态成员
super 也可用于访问父类的静态方法或变量(尽管静态成员属于类而非实例)。
class Base {
public static void staticMethod() {
System.out.println("父类的静态方法");
}
}
class Sub extends Base {
public static void staticMethod() {
System.out.println("子类的静态方法");
}
public void callParentStatic() {
super.staticMethod(); // 调用父类的静态方法
}
}
注意事项
super()必须在构造函数的第一行public Child() { // super(); // 编译器会自动添加,若父类有无参构造函数 // 其他代码... }避免循环构造函数调用 子类构造函数调用父类构造函数,父类构造函数又调用子类构造函数,会导致栈溢出。
静态方法中不能使用
super静态方法属于类,不依赖于实例,因此没有super引用。super与this的区别this:引用当前对象。super:引用父类的成员。
总结
super 关键字的核心作用是在子类中访问父类的成员,解决继承中的命名冲突和构造函数调用问题。合理使用 super 可以提高代码的可维护性和复用性。