Java 继承与多态:从"是什么"到"能做什么"的设计思维

前言

学继承与多态。JS 的继承是原型链,灵活但混乱。Java 的继承是严格的树形结构,配合多态,代码扩展性极强。


1. 继承:单继承,严格层级

java 复制代码
public class Dog extends Animal {
    public Dog(String name, int age, String breed) {
        super(name, age);  // 必须第一行
    }
}

Java 只支持单继承,避免了 C++ 多继承的菱形问题。super() 调用父类构造,必须放在第一行。

2. 方法重写:@Override 是保险

java 复制代码
@Override
public void eat() {
    System.out.println(name + "在吃狗粮");
}

@Override 注解让编译器检查是否真的在重写。JS 没有这机制,拼写错误变成新增方法,坑死人。

3. 多态:父类引用,子类实现

java 复制代码
Animal animal = new Dog("旺财", 3, "金毛");
animal.eat();  // 旺财在吃狗粮

编译时看左边(Animal 有什么方法),运行时看右边(Dog 怎么实现)。这是 Java 的核心设计模式基础。

4. 抽象类 vs 接口

场景 用抽象类 用接口
代码复用
多继承需求 ✅(多实现)
定义行为规范 可以 更适合

JDK 8 后接口有了默认方法,但核心区别仍在:抽象类是"是什么",接口是"能做什么"。

5. 实战:员工工资系统

Employee.java(员工抽象类):

java 复制代码
public abstract class Employee {
    protected String id;
    protected String name;
    
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    // 抽象方法:不同员工计算工资方式不同
    public abstract double calculateSalary();
    
    public void showInfo() {
        System.out.println("工号:" + id + ",姓名:" + name);
    }
}

SalariedEmployee.java(月薪员工):

java 复制代码
public class SalariedEmployee extends Employee {
    private double monthlySalary;
    
    public SalariedEmployee(String id, String name, double monthlySalary) {
        super(id, name);
        this.monthlySalary = monthlySalary;
    }
    
    @Override
    public double calculateSalary() {
        return monthlySalary;
    }
}

HourlyEmployee.java(时薪员工):

java 复制代码
public class HourlyEmployee extends Employee {
    private double hourlyRate;
    private int hoursWorked;
    
    public HourlyEmployee(String id, String name, double hourlyRate, int hoursWorked) {
        super(id, name);
        this.hourlyRate = hourlyRate;
        this.hoursWorked = hoursWorked;
    }
    
    @Override
    public double calculateSalary() {
        return hourlyRate * hoursWorked;
    }
}

PayrollSystem.java(工资系统):

java 复制代码
public class PayrollSystem {
    public static void main(String[] args) {
        // 多态:父类引用指向不同子类对象
        Employee[] employees = new Employee[3];
        employees[0] = new SalariedEmployee("001", "张三", 15000);
        employees[1] = new HourlyEmployee("002", "李四", 100, 160);
        employees[2] = new SalariedEmployee("003", "王五", 20000);
        
        System.out.println("=== 工资发放 ===");
        for (Employee emp : employees) {
            emp.showInfo();
            System.out.println("本月工资:" + emp.calculateSalary() + "元");
            System.out.println("---");
        }
    }
}

设计亮点:

  • Employee 抽象类定义统一接口 calculateSalary()
  • SalariedEmployeeHourlyEmployee 各自实现
  • PayrollSystem 用多态统一处理,新增员工类型无需修改

多态让代码"对扩展开放,对修改封闭"。新增一种员工,只需新增一个类,不用改工资计算逻辑。

相关推荐
进击的程序猿~4 分钟前
Go Slice源码深度解析指南
开发语言·后端·golang
HAPPY酷9 分钟前
【ROS2】16G 内存笔记本跑 ROS2 仿真?VMware 虚拟机“保姆级”配置指南 (R9 7940HX + RTX 4060)
java·linux·ide·windows·pycharm
程序员爱钓鱼15 分钟前
Rust 变量与不可变性:为什么默认不能修改变量?
前端·后端·rust
折哥的程序人生 · 物流技术专研9 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
GoGeekBaird9 小时前
我开源了 BeeWeave,给 AI Agent 搭一个越用越懂你的知识创作台
后端·github
researcher-Jiang9 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
西门吹-禅11 小时前
java springboot N+1问题
java·开发语言·spring boot
DLYSB_11 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
weixin_BYSJ198711 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
AI小码11 小时前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api