Skip to content

11.4 super 关键字

super 关键字的概念

super 是 Java 中的一个关键字,它表示父类的引用。super 关键字在子类中使用,用于访问父类的属性和方法。

super 关键字的用法

1. 访问父类的构造方法

在子类的构造方法中,可以使用 super() 调用父类的构造方法。

语法:

java
super([参数]);

示例:

java
public class Parent {
    public Parent() {
        System.out.println("Parent constructor");
    }
    
    public Parent(String name) {
        System.out.println("Parent constructor with name: " + name);
    }
}

public class Child extends Parent {
    public Child() {
        super(); // 调用父类的无参构造方法
        System.out.println("Child constructor");
    }
    
    public Child(String name) {
        super(name); // 调用父类的有参构造方法
        System.out.println("Child constructor with name: " + name);
    }
}

2. 访问父类的属性

在子类中,可以使用 super.属性名 访问父类的属性。

语法:

java
super.属性名;

示例:

java
public class Parent {
    protected String name = "Parent";
}

public class Child extends Parent {
    private String name = "Child";
    
    public void printNames() {
        System.out.println("Child name: " + name); // 访问子类的属性
        System.out.println("Parent name: " + super.name); // 访问父类的属性
    }
}

3. 访问父类的方法

在子类中,可以使用 super.方法名() 调用父类的方法。

语法:

java
super.方法名([参数]);

示例:

java
public class Parent {
    public void method() {
        System.out.println("Parent method");
    }
}

public class Child extends Parent {
    @Override
    public void method() {
        super.method(); // 调用父类的方法
        System.out.println("Child method");
    }
}

示例:super 关键字的基本使用

示例 1:调用父类的构造方法

java
// 父类:Person
public class Person {
    private String name;
    private int age;
    
    public Person() {
        System.out.println("Person constructor");
    }
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person constructor with name and age");
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
}

// 子类:Student
public class Student extends Person {
    private int studentId;
    
    public Student() {
        super(); // 调用父类的无参构造方法
        System.out.println("Student constructor");
    }
    
    public Student(String name, int age, int studentId) {
        super(name, age); // 调用父类的有参构造方法
        this.studentId = studentId;
        System.out.println("Student constructor with name, age, and studentId");
    }
    
    public int getStudentId() {
        return studentId;
    }
}

// 测试类
public class SuperExample {
    public static void main(String[] args) {
        System.out.println("Creating Student with no parameters:");
        Student student1 = new Student();
        
        System.out.println("\nCreating Student with parameters:");
        Student student2 = new Student("John", 18, 1001);
        System.out.println("Name: " + student2.getName());
        System.out.println("Age: " + student2.getAge());
        System.out.println("Student ID: " + student2.getStudentId());
    }
}

示例 2:访问父类的属性

java
// 父类:Parent
public class Parent {
    protected String name = "Parent";
    protected int age = 40;
}

// 子类:Child
public class Child extends Parent {
    private String name = "Child";
    private int age = 10;
    
    public void printInfo() {
        System.out.println("Child name: " + name);
        System.out.println("Child age: " + age);
        System.out.println("Parent name: " + super.name);
        System.out.println("Parent age: " + super.age);
    }
}

// 测试类
public class SuperExample {
    public static void main(String[] args) {
        Child child = new Child();
        child.printInfo();
    }
}

示例 3:访问父类的方法

java
// 父类:Animal
public class Animal {
    public void makeSound() {
        System.out.println("Animal makes sound");
    }
    
    public void eat() {
        System.out.println("Animal eats");
    }
}

// 子类:Dog
public class Dog extends Animal {
    @Override
    public void makeSound() {
        super.makeSound(); // 调用父类的方法
        System.out.println("Dog barks");
    }
    
    @Override
    public void eat() {
        System.out.println("Dog eats bones");
    }
}

// 测试类
public class SuperExample {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();
        dog.eat();
    }
}

示例 4:多层继承中的 super

java
// 祖父类:Grandparent
public class Grandparent {
    public void method() {
        System.out.println("Grandparent method");
    }
}

// 父类:Parent
public class Parent extends Grandparent {
    @Override
    public void method() {
        super.method(); // 调用祖父类的方法
        System.out.println("Parent method");
    }
}

// 子类:Child
public class Child extends Parent {
    @Override
    public void method() {
        super.method(); // 调用父类的方法
        System.out.println("Child method");
    }
}

// 测试类
public class SuperExample {
    public static void main(String[] args) {
        Child child = new Child();
        child.method();
    }
}

super 关键字的使用场景

1. 调用父类的构造方法

当子类需要初始化父类的属性时,使用 super() 调用父类的构造方法。

示例:

java
public class Parent {
    private String name;
    
    public Parent(String name) {
        this.name = name;
    }
}

public class Child extends Parent {
    private int age;
    
    public Child(String name, int age) {
        super(name); // 调用父类的构造方法初始化 name
        this.age = age;
    }
}

2. 访问父类的属性

当子类和父类有同名属性时,使用 super.属性名 访问父类的属性。

示例:

java
public class Parent {
    protected int value = 100;
}

public class Child extends Parent {
    private int value = 200;
    
    public void printValues() {
        System.out.println("Child value: " + value);
        System.out.println("Parent value: " + super.value);
    }
}

3. 调用父类的方法

当子类重写了父类的方法,但仍然需要调用父类的方法时,使用 super.方法名() 调用父类的方法。

示例:

java
public class Parent {
    public void doSomething() {
        System.out.println("Parent is doing something");
    }
}

public class Child extends Parent {
    @Override
    public void doSomething() {
        super.doSomething(); // 调用父类的方法
        System.out.println("Child is doing something");
    }
}

注意事项

  1. super() 必须是构造方法的第一条语句:在子类构造方法中调用父类构造方法时,super() 必须是第一条语句。

  2. super 不能在静态方法中使用super 关键字不能在静态方法中使用,因为静态方法属于类,不属于对象。

  3. super 不能在类的外部使用super 关键字只能在类的内部使用,不能在类的外部使用。

  4. super 与 this 的区别super 表示父类的引用,this 表示当前对象的引用。

示例:super 与 this 的区别

java
public class Parent {
    protected String name = "Parent";
    
    public void method() {
        System.out.println("Parent method");
    }
}

public class Child extends Parent {
    private String name = "Child";
    
    public void method() {
        System.out.println("Child method");
    }
    
    public void printInfo() {
        System.out.println("Child name: " + this.name); // 访问当前对象的属性
        System.out.println("Parent name: " + super.name); // 访问父类的属性
        
        this.method(); // 调用当前对象的方法
        super.method(); // 调用父类的方法
    }
}

// 测试类
public class SuperThisExample {
    public static void main(String[] args) {
        Child child = new Child();
        child.printInfo();
    }
}

常见问题

1. 构造方法中 super() 不是第一条语句

症状:编译错误:Constructor call must be the first statement in a constructor

解决方案:在子类构造方法中,super() 必须是第一条语句。

示例:

java
public class Parent {
    public Parent() {
    }
}

public class Child extends Parent {
    public Child() {
        System.out.println("Hello");
        super(); // 错误:super() 必须是第一条语句
    }
}

2. 在静态方法中使用 super

症状:编译错误:Cannot use super in a static context

解决方案super 关键字不能在静态方法中使用。

示例:

java
public class Parent {
    public static void method() {
    }
}

public class Child extends Parent {
    public static void method() {
        super.method(); // 错误:不能在静态方法中使用 super
    }
}

3. 访问父类的私有属性

症状:编译错误:The field Parent.privateField is not visible

解决方案:父类的私有属性不能直接访问,需要通过公共的 getter 方法访问。

示例:

java
public class Parent {
    private String name = "Parent";
    
    public String getName() {
        return name;
    }
}

public class Child extends Parent {
    public void printName() {
        // 错误:不能直接访问父类的私有属性
        // System.out.println(super.name);
        
        // 正确:通过 getter 方法访问
        System.out.println(getName());
    }
}

最佳实践

  1. 在子类构造方法中调用父类构造方法:确保父类的属性得到正确初始化

  2. 合理使用 super 访问父类的属性和方法:当子类和父类有同名属性或方法时,使用 super 访问父类的属性和方法

  3. 在重写方法时调用父类的方法:当子类重写父类的方法时,如果需要保留父类的功能,可以调用父类的方法

  4. 避免在静态方法中使用 super:super 关键字不能在静态方法中使用

  5. 理解 super 与 this 的区别:super 表示父类的引用,this 表示当前对象的引用

总结

super 关键字是 Java 中的一个重要关键字,它表示父类的引用。super 关键字的主要用途包括:

  1. 调用父类的构造方法:在子类构造方法中使用 super() 调用父类的构造方法

  2. 访问父类的属性:在子类中使用 super.属性名 访问父类的属性

  3. 访问父类的方法:在子类中使用 super.方法名() 调用父类的方法

通过合理使用 super 关键字,可以使子类更好地继承和扩展父类的功能,提高代码的可读性和可维护性。

© 2026 编程马·菜鸟教程 版权所有