super 关键字
概述
super
关键字用于引用父类的成员、调用父类的构造器和方法。它是实现继承机制的重要工具。
语法格式
super.variable // 访问父类变量
super.method() // 调用父类方法
super(parameters) // 调用父类构造器
基本用法
// 父类
class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + " 正在吃东西");
}
public void sleep() {
System.out.println(name + " 正在睡觉");
}
public void displayInfo() {
System.out.println("动物信息:");
System.out.println("名字:" + name);
System.out.println("年龄:" + age);
}
}
// 子类
class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造器
this.breed = breed;
}
@Override
public void eat() {
super.eat(); // 调用父类方法
System.out.println(name + " 吃狗粮");
}
@Override
public void displayInfo() {
super.displayInfo(); // 调用父类方法
System.out.println("品种:" + breed);
}
public void bark() {
System.out.println(super.name + " 在汪汪叫"); // 访问父类成员
}
}
public class SuperExample {
public static void main(String[] args) {
Dog dog = new Dog("旺财", 3, "金毛");
dog.eat();
dog.displayInfo();
dog.bark();
}
}
构造器链调用
class Vehicle {
protected String brand;
protected String model;
protected int year;
public Vehicle() {
this("未知品牌", "未知型号", 2020);
System.out.println("Vehicle 无参构造器");
}
public Vehicle(String brand) {
this(brand, "未知型号", 2020);
System.out.println("Vehicle 单参构造器");
}
public Vehicle(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
System.out.println("Vehicle 三参构造器");
}
public void start() {
System.out.println(brand + " " + model + " 启动");
}
}
class Car extends Vehicle {
private int doors;
public Car() {
super(); // 调用父类无参构造器
this.doors = 4;
System.out.println("Car 无参构造器");
}
public Car(String brand, int doors) {
super(brand); // 调用父类单参构造器
this.doors = doors;
System.out.println("Car 两参构造器");
}
public Car(String brand, String model, int year, int doors) {
super(brand, model, year); // 调用父类三参构造器
this.doors = doors;
System.out.println("Car 四参构造器");
}
@Override
public void start() {
super.start(); // 调用父类方法
System.out.println("检查 " + doors + " 个车门");
}
}
public class ConstructorChainExample {
public static void main(String[] args) {
System.out.println("=== 创建Car() ===");
Car car1 = new Car();
car1.start();
System.out.println("\n=== 创建Car(brand, doors) ===");
Car car2 = new Car("丰田", 2);
car2.start();
System.out.println("\n=== 创建Car(brand, model, year, doors) ===");
Car car3 = new Car("本田", "雅阁", 2021, 4);
car3.start();
}
}
方法重写中的super
class Employee {
protected String name;
protected double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public double calculatePay() {
return salary;
}
public void displayInfo() {
System.out.println("员工:" + name);
System.out.println("基本工资:" + salary);
}
public String getRole() {
return "员工";
}
}
class Manager extends Employee {
private double bonus;
private int teamSize;
public Manager(String name, double salary, double bonus, int teamSize) {
super(name, salary);
this.bonus = bonus;
this.teamSize = teamSize;
}
@Override
public double calculatePay() {
double basePay = super.calculatePay(); // 调用父类方法
return basePay + bonus;
}
@Override
public void displayInfo() {
super.displayInfo(); // 调用父类方法
System.out.println("奖金:" + bonus);
System.out.println("团队规模:" + teamSize);
System.out.println("总薪资:" + calculatePay());
}
@Override
public String getRole() {
return "经理 (" + super.getRole() + ")"; // 扩展父类返回值
}
public void manageTeam() {
System.out.println(super.name + " 正在管理 " + teamSize + " 人的团队");
}
}
class Developer extends Employee {
private String programmingLanguage;
private int projectsCompleted;
public Developer(String name, double salary, String language) {
super(name, salary);
this.programmingLanguage = language;
this.projectsCompleted = 0;
}
@Override
public double calculatePay() {
double basePay = super.calculatePay();
// 每完成一个项目额外奖励1000
return basePay + (projectsCompleted * 1000);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("编程语言:" + programmingLanguage);
System.out.println("完成项目:" + projectsCompleted);
System.out.println("总薪资:" + calculatePay());
}
public void completeProject() {
projectsCompleted++;
System.out.println(super.name + " 完成了一个 " + programmingLanguage + " 项目");
}
}
public class MethodOverrideExample {
public static void main(String[] args) {
Manager manager = new Manager("张经理", 15000, 5000, 8);
Developer developer = new Developer("李开发", 12000, "Java");
System.out.println("=== 经理信息 ===");
manager.displayInfo();
System.out.println("角色:" + manager.getRole());
manager.manageTeam();
System.out.println("\n=== 开发者信息 ===");
developer.displayInfo();
developer.completeProject();
developer.completeProject();
System.out.println("\n=== 项目完成后 ===");
developer.displayInfo();
}
}
变量隐藏处理
class Parent {
protected String message = "父类消息";
protected int value = 100;
public void printMessage() {
System.out.println("父类方法: " + message);
}
public void showValue() {
System.out.println("父类值: " + value);
}
}
class Child extends Parent {
protected String message = "子类消息"; // 隐藏父类变量
private int value = 200; // 隐藏父类变量
public void printMessage() {
System.out.println("子类方法: " + message);
System.out.println("父类消息通过super: " + super.message);
}
public void showValue() {
System.out.println("子类值: " + value);
System.out.println("父类值通过super: " + super.value);
}
public void demonstrateHiding() {
// 直接访问是子类的变量
System.out.println("直接访问message: " + message);
System.out.println("通过super访问: " + super.message);
// 调用方法时的区别
this.printMessage(); // 调用子类方法
super.printMessage(); // 调用父类方法
}
}
public class VariableHidingExample {
public static void main(String[] args) {
Child child = new Child();
child.demonstrateHiding();
System.out.println("\n=== 值对比 ===");
child.showValue();
}
}
抽象类中的super
abstract class Shape {
protected String color;
protected double area;
public Shape(String color) {
this.color = color;
this.area = 0.0;
}
public abstract void calculateArea();
public void displayInfo() {
calculateArea(); // 调用子类实现
System.out.println("颜色: " + color);
System.out.println("面积: " + area);
}
protected void setArea(double area) {
this.area = area;
}
}
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color); // 调用父类构造器
this.radius = radius;
}
@Override
public void calculateArea() {
double calculatedArea = Math.PI * radius * radius;
super.setArea(calculatedArea); // 调用父类方法
}
@Override
public void displayInfo() {
System.out.println("圆形信息:");
System.out.println("半径: " + radius);
super.displayInfo(); // 调用父类方法
}
}
class Rectangle extends Shape {
private double width, height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public void calculateArea() {
super.setArea(width * height);
}
@Override
public void displayInfo() {
System.out.println("矩形信息:");
System.out.println("宽度: " + width + ", 高度: " + height);
super.displayInfo();
}
}
public class AbstractClassExample {
public static void main(String[] args) {
Shape circle = new Circle("红色", 5.0);
Shape rectangle = new Rectangle("蓝色", 10.0, 6.0);
circle.displayInfo();
System.out.println();
rectangle.displayInfo();
}
}
最佳实践
构造器中使用super:
class Parent { public Parent(String name) { // 初始化逻辑 } } class Child extends Parent { public Child(String name, int age) { super(name); // 必须是第一行 // 子类初始化逻辑 } }
方法重写时保留父类行为:
@Override public void method() { super.method(); // 保留父类行为 // 添加额外功能 }
避免过度使用super:
// 不必要的super使用 public void method() { super.publicMethod(); // 可以直接调用 } // 合理的super使用 public void method() { super.overriddenMethod(); // 明确调用父类版本 }
super关键字是Java继承机制的核心,正确使用它可以有效地复用父类功能并扩展行为。