在 Java 面向对象编程中,** 继承(Inheritance)方法重写(Method Overriding)** 是核心知识点,也是实现代码复用、多态特性的关键。今天通过「银行与利息」实验,我们手把手掌握这两个知识点,理解子类如何继承父类、如何重写父类方法,以及 super 关键字的用法。

一、实验需求分析

需要实现父类银行(Bank) + 两个子类银行(建设银行、大连银行),完成利息计算功能:

  1. 父类 Bank:定义基础属性(存款金额、存期、利率)、通用利息计算方法、利率设置方法;
  2. 子类 ConstructionBank(建设银行):按年利息 + 天利息计算,日利率 0.0001;
  3. 子类 BankOfDalian(大连银行):按年利息 + 天利息计算,日利率 0.00012;
  4. 测试类:存入 8000 元,存期 8 年 236 天,对比两家银行利息差额。

核心考点:继承、方法重写、super 关键字调用父类方法 / 属性

二、完整代码实现

1. 父类 Bank.java

父类封装所有银行的通用属性和方法,子类直接继承复用,无需重复编写。

public class Bank {
    int savedMoney;    // 存款金额
    int year;          // 存期(年)
    double interest;   // 利息
    double interestRate = 0.29; // 默认利率

    // 通用利息计算方法
    public double computerInterest() {
        interest = year * interestRate * savedMoney;
        return interest;
    }

    // 设置利率方法
    public void setInterestRate(double rate) {
        interestRate = rate;
    }
}

2. 子类 ConstructionBank.java

继承 Bank重写利息计算方法,实现建设银行的计息规则,用 super 调用父类的计息方法。

public class ConstructionBank extends Bank {
    double year; // 子类自定义存期(支持小数,如8.236年)

    // 方法重写:覆盖父类的computerInterest()
    @Override
    public double computerInterest() {
        super.year = (int) year; // 取整数年,赋值给父类的year
        double r = year - (int) year; // 取小数部分(代表天数)
        int day = (int) (r * 1000); // 转换为实际天数
        // 代码1:super调用父类的computerInterest(),计算年利息
        double yearInterest = super.computerInterest();
        double dayInterest = day * 0.0001 * savedMoney; // 日利息
        interest = yearInterest + dayInterest; // 总利息
        System.out.printf("%d 元存在建设银行%d 年零%d 天的利息:%f 元\n",
                savedMoney, super.year, day, interest);
        return interest;
    }
}

3. 子类 BankOfDalian.java

逻辑与建设银行一致,仅日利率不同,同样通过方法重写实现差异化功能。

public class BankOfDalian extends Bank {
    double year;

    @Override
    public double computerInterest() {
        super.year = (int) year;
        double r = year - (int) year;
        int day = (int) (r * 1000);
        // 代码2:super调用父类的computerInterest()
        double yearInterest = super.computerInterest();
        double dayInterest = day * 0.00012 * savedMoney; // 日利率不同
        interest = yearInterest + dayInterest;
        System.out.printf("%d 元存在大连银行%d 年零%d 天的利息:%f 元\n",
                savedMoney, super.year, day, interest);
        return interest;
    }
}

4. 测试类 SaveMoney.java

创建子类对象,赋值属性,调用方法,对比利息差额。

public class SaveMoney {
    public static void main(String args[]) {
        int amount = 8000;
        // 建设银行计息
        ConstructionBank bank1 = new ConstructionBank();
        bank1.savedMoney = amount;
        bank1.year = 8.236; // 8年236天
        bank1.setInterestRate(0.035);
        double interest1 = bank1.computerInterest();

        // 大连银行计息
        BankOfDalian bank2 = new BankOfDalian();
        bank2.savedMoney = amount;
        bank2.year = 8.236;
        bank2.setInterestRate(0.035);
        double interest2 = bank2.computerInterest();

        // 输出利息差额
        System.out.printf("两个银行利息相差%f 元\n", interest2 - interest1);
    }
}

运行结果

8000 元存在建设银行8 年零236 天的利息:2302.880000 元
8000 元存在大连银行8 年零236 天的利息:2340.640000 元
两个银行利息相差37.760000 元

三、核心知识点深度解析

1. 继承(extends)

  • 语法子类 extends 父类,子类自动拥有父类非私有的属性和方法;
  • 作用:代码复用,父类定义通用逻辑,子类只需要实现差异化功能;
  • 本实验中:ConstructionBankBankOfDalian 继承 Bank,直接复用 savedMoneyinterestRate 属性和 setInterestRate() 方法。

2. 方法重写(Override)

  • 定义:子类对父类已有的方法,重新编写方法体,实现子类专属逻辑;
  • 规则
    1. 方法名、参数列表、返回值类型必须和父类完全一致;
    2. 子类方法权限不能低于父类(父类public,子类必须public);
    3. 必须添加 @Override 注解(校验重写是否规范);
  • 本实验中:两个子类都重写了 computerInterest(),实现了各自的计息规则。

3. super 关键字(核心)

super 是子类调用父类的钥匙,主要作用:

  1. 调用父类的方法super.computerInterest()(实验中代码 1、代码 2);
  2. 调用父类的属性super.year(给父类的存期赋值);
  3. 调用父类的构造方法super()(本实验未用到)。

注意:子类和父类有同名属性时,必须用 super 区分父类属性,否则会调用子类自身属性。

4. 方法隐藏与调用

当子类重写父类方法后,子类对象默认调用重写后的方法;如果需要调用父类原本的方法,必须用 super.方法名(),这就是实验中「调用隐藏的父类方法」的含义。

四、总结

  1. 继承解决了代码复用问题,让子类共享父类的属性和方法;
  2. 方法重写实现了子类的差异化功能,是多态的基础;
  3. super 关键字是子类访问父类成员的核心,必须熟练掌握;
  4. 面向对象编程思想:抽取共性到父类,保留特性到子类,让代码更简洁、易维护。

更多推荐