Appearance
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");
}
}注意事项
super() 必须是构造方法的第一条语句:在子类构造方法中调用父类构造方法时,
super()必须是第一条语句。super 不能在静态方法中使用:
super关键字不能在静态方法中使用,因为静态方法属于类,不属于对象。super 不能在类的外部使用:
super关键字只能在类的内部使用,不能在类的外部使用。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());
}
}最佳实践
在子类构造方法中调用父类构造方法:确保父类的属性得到正确初始化
合理使用 super 访问父类的属性和方法:当子类和父类有同名属性或方法时,使用 super 访问父类的属性和方法
在重写方法时调用父类的方法:当子类重写父类的方法时,如果需要保留父类的功能,可以调用父类的方法
避免在静态方法中使用 super:super 关键字不能在静态方法中使用
理解 super 与 this 的区别:super 表示父类的引用,this 表示当前对象的引用
总结
super 关键字是 Java 中的一个重要关键字,它表示父类的引用。super 关键字的主要用途包括:
调用父类的构造方法:在子类构造方法中使用
super()调用父类的构造方法访问父类的属性:在子类中使用
super.属性名访问父类的属性访问父类的方法:在子类中使用
super.方法名()调用父类的方法
通过合理使用 super 关键字,可以使子类更好地继承和扩展父类的功能,提高代码的可读性和可维护性。
