Java基础(八):封装、继承、多态性实战解析

📅 2026/7/15 11:53:19 👁️ 阅读次数 📝 编程学习
Java基础(八):封装、继承、多态性实战解析

1. 封装性实战解析

封装是面向对象编程的第一道防线,它像保险箱一样保护着数据安全。我见过太多新手直接暴露成员变量导致数据混乱的案例,比如下面这个反面教材:

// 危险示范:裸奔的成员变量 class Employee { public String name; public double salary; }

正确的封装姿势应该是这样的:

public class Employee { private String name; private double baseSalary; // 薪资校验逻辑 public void setBaseSalary(double salary) { if(salary < 0) { throw new IllegalArgumentException("薪资不能为负数"); } this.baseSalary = salary; } // 计算税后工资(隐藏计算细节) public double getNetSalary() { return baseSalary * 0.85; // 模拟扣除15%税费 } }

封装的核心价值在于:

  • 数据校验:像门卫一样检查数据合法性
  • 隐藏实现:修改内部计算逻辑不影响调用方
  • 访问控制:通过权限修饰符管理可见性

四种访问修饰符的权限对比:

修饰符本类同包不同包子类不同包非子类
private
缺省
protected
public

2. 继承体系构建技巧

继承不只是代码复用,更是构建类层次关系的艺术。我们以薪资管理系统为例:

// 基础员工类 class Employee { private String id; private String name; public Employee(String id, String name) { this.id = id; this.name = name; } public double calculateSalary() { return 0; } } // 经理类继承员工 class Manager extends Employee { private double bonus; public Manager(String id, String name, double bonus) { super(id, name); // 必须调用父类构造器 this.bonus = bonus; } @Override public double calculateSalary() { return 10000 + bonus; // 基础薪资+奖金 } }

继承使用中的黄金法则:

  1. 里氏替换原则:子类必须能替换父类
  2. 慎用继承:优先考虑组合而非继承
  3. 避免多层继承:一般不超过3层继承链

常见误区警示:

  • 子类构造器必须调用super()
  • 父类private成员不可直接访问
  • 方法重写时访问权限不能更严格

3. 多态性的魔法

多态让代码像变形金刚一样灵活。来看个薪资计算的经典案例:

public class SalarySystem { public static void main(String[] args) { Employee[] staff = { new Manager("M001", "张总", 5000), new Programmer("P001", "李工", 10) }; // 多态调用 for(Employee e : staff) { System.out.println(e.getName() + "的薪资:" + e.calculateSalary()); } } } class Programmer extends Employee { private int overtimeHours; public Programmer(String id, String name, int hours) { super(id, name); this.overtimeHours = hours; } @Override public double calculateSalary() { return 8000 + overtimeHours * 100; // 基础+加班费 } }

多态的实现机制:

  1. 向上转型Employee e = new Manager()
  2. 动态绑定:运行时确定实际类型
  3. 方法表:JVM通过虚方法表实现

类型转换的注意事项:

if(employee instanceof Manager) { Manager m = (Manager)employee; // 安全向下转型 m.approveLeave(); // 调用子类特有方法 }

4. 综合案例:薪资管理系统

让我们用三大特性构建完整系统:

// 抽象基类 abstract class Employee { // 公共字段和方法... public abstract double calculateSalary(); } // 接口定义行为 interface BonusEligible { double calculateBonus(); } // 销售类实现多继承 class Sales extends Employee implements BonusEligible { private double salesAmount; @Override public double calculateSalary() { return 3000 + salesAmount * 0.1; } @Override public double calculateBonus() { return salesAmount > 10000 ? 2000 : 1000; } }

系统设计要点:

  1. 抽象类定义公共模板
  2. 接口扩展额外能力
  3. 枚举管理类型常量

测试用例:

Employee emp = new Sales("S001", "王销售", 15000); if(emp instanceof BonusEligible) { BonusEligible be = (BonusEligible)emp; System.out.println("奖金:" + be.calculateBonus()); }

5. 常见问题解决方案

问题1:如何选择继承还是接口?

  • 继承:is-a关系,代码复用
  • 接口:has-a能力,多态扩展

问题2:多态性能优化

  • 避免频繁instanceof检查
  • 使用策略模式替代条件判断

问题3:构造器链调用

public class Director extends Manager { public Director(String id, String name) { super(id, name, 0); // 必须放在第一行 // 其他初始化... } }

实际项目中,我推荐使用Lombok简化代码:

@Data @AllArgsConstructor public class Department { private String name; private List<Employee> staff; }