Java面向对象编程:封装、继承与多态深度解析

面向对象编程(OOP)是Java的核心思想,它让代码更加模块化、可重用和易维护。今天,我们将深入探讨OOP的三大支柱:封装、继承和多态,这是每个Java程序员必须掌握的核心概念。

引入:为什么需要面向对象编程?

想象一下,你正在开发一个游戏系统:

  • 游戏中有玩家(Player)、敌人(Enemy)、道具(Item)等多种角色
  • 这些角色都有共同的特征(如位置、血量),但也有各自的特殊能力
  • 如果不使用OOP,代码会变得混乱不堪,难以维护

使用面向对象编程,我们可以将现实世界的实体抽象为"对象",每个对象都有自己的数据和行为,就像乐高积木一样,可以灵活组合。

一、封装:保护数据的"保险箱"

1.1 什么是封装?

封装就是将数据和对数据的操作包装在一起,并隐藏实现细节。就像银行的ATM机:

  • 你只能通过界面按钮(公共方法)操作
  • 不能直接接触内部的现金(私有数据)
  • ATM内部的运作机制对你隐藏(实现细节)

1.2 封装的实现示例

java 复制代码
public class EncapsulationDemo {
    public static void main(String[] args) {
        // 创建银行账户
        BankAccount account = new BankAccount("张三", "123456");
        
        // ✅ 正确的访问方式:通过公共方法
        account.deposit(1000);      // 存款
        account.withdraw(500);      // 取款
        account.displayBalance();   // 查看余额
        
        // ❌ 错误的方式:直接访问私有数据
        // account.balance = 1000000;  // 编译错误!无法直接访问
        // account.password = "hack";  // 编译错误!无法直接访问
        
        System.out.println("\n尝试非法操作:");
        account.withdraw(10000);    // 余额不足,安全被拒绝
        
        System.out.println("\n尝试破解密码:");
        // 无法直接修改密码,只能通过验证流程
        account.changePassword("wrong", "new123");  // 失败
        account.changePassword("123456", "new123"); // 成功
    }
}

class BankAccount {
    // 私有属性:外部不能直接访问(封装的精髓)
    private String accountHolder;  // 账户持有人
    private String password;       // 密码
    private double balance;        // 余额
    private final String accountNumber; // 账号(final表示不可变)
    
    // 构造方法
    public BankAccount(String holder, String pwd) {
        this.accountHolder = holder;
        this.password = pwd;
        this.balance = 0.0;
        this.accountNumber = generateAccountNumber();
    }
    
    // 公共方法:存款
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("成功存款:" + amount + "元");
            logTransaction("存款", amount);
        } else {
            System.out.println("存款金额必须大于0");
        }
    }
    
    // 公共方法:取款
    public void withdraw(double amount) {
        if (amount <= 0) {
            System.out.println("取款金额必须大于0");
        } else if (amount > balance) {
            System.out.println("余额不足!当前余额:" + balance);
        } else {
            balance -= amount;
            System.out.println("成功取款:" + amount + "元");
            logTransaction("取款", amount);
        }
    }
    
    // 公共方法:显示余额
    public void displayBalance() {
        System.out.println("账户:" + accountNumber);
        System.out.println("持有人:" + accountHolder);
        System.out.println("当前余额:" + balance + "元");
    }
    
    // 公共方法:修改密码(需要验证原密码)
    public boolean changePassword(String oldPwd, String newPwd) {
        if (this.password.equals(oldPwd)) {
            this.password = newPwd;
            System.out.println("密码修改成功");
            return true;
        } else {
            System.out.println("原密码错误,修改失败");
            return false;
        }
    }
    
    // 私有方法:只能在类内部使用(封装的实现细节)
    private String generateAccountNumber() {
        // 模拟生成账号:时间戳 + 随机数
        return "ACC" + System.currentTimeMillis() % 10000;
    }
    
    private void logTransaction(String type, double amount) {
        // 记录交易日志
        System.out.println("[日志] " + type + " " + amount + "元");
    }
    
    // Getter方法:提供对私有属性的受控访问
    public String getAccountHolder() {
        return accountHolder;
    }
    
    public double getBalance() {
        return balance;
    }
    
    // 没有提供password的getter,保护密码安全
    
    // Setter方法:提供对私有属性的受控修改
    public void setAccountHolder(String holder) {
        if (holder != null && !holder.trim().isEmpty()) {
            this.accountHolder = holder;
        }
    }
}

1.3 封装的好处

  1. 数据安全:防止外部代码随意修改对象状态
  2. 易于维护:内部实现可以改变而不影响外部代码
  3. 代码清晰:明确区分"可以做什么"和"如何实现"
  4. 减少耦合:类之间的关系更清晰,更易于修改

二、继承:代码复用的"基因传递"

2.1 什么是继承?

继承允许一个类(子类)继承另一个类(父类)的属性和方法。就像生物学中的遗传:

  • 孩子继承父母的特征
  • 但孩子也可以有自己独特的特征
  • 继承建立了类之间的层次关系

2.2 继承的实现示例

java 复制代码
public class InheritanceDemo {
    public static void main(String[] args) {
        System.out.println("=== 继承示例:车辆系统 ===\n");
        
        // 创建不同类型的车辆
        Vehicle genericVehicle = new Vehicle("通用车辆", 2020);
        Car myCar = new Car("丰田卡罗拉", 2022, 4);
        Motorcycle myBike = new Motorcycle("本田CBR", 2023, true);
        ElectricCar tesla = new ElectricCar("特斯拉Model 3", 2023, 4, 75);
        
        // 展示多态性:父类引用指向子类对象
        Vehicle[] vehicles = {genericVehicle, myCar, myBike, tesla};
        
        for (Vehicle vehicle : vehicles) {
            vehicle.displayInfo();
            vehicle.start();  // 多态:同一个方法,不同行为
            System.out.println();
        }
        
        // 访问子类特有的方法
        System.out.println("=== 子类特有方法 ===");
        myCar.openSunroof();
        myBike.doWheelie();
        tesla.chargeBattery();
    }
}

// 父类:车辆
class Vehicle {
    // 受保护属性:子类可以访问,外部不能
    protected String brand;
    protected int year;
    
    // 构造方法
    public Vehicle(String brand, int year) {
        this.brand = brand;
        this.year = year;
    }
    
    // 公共方法:启动车辆
    public void start() {
        System.out.println(brand + " 正在启动...");
    }
    
    // 公共方法:停止车辆
    public void stop() {
        System.out.println(brand + " 已停止");
    }
    
    // 公共方法:显示信息
    public void displayInfo() {
        System.out.println("品牌:" + brand);
        System.out.println("年份:" + year);
    }
    
    // 计算年龄
    public int calculateAge(int currentYear) {
        return currentYear - year;
    }
}

// 子类:汽车(继承Vehicle)
class Car extends Vehicle {
    // 子类特有的属性
    private int doorCount;
    
    // 子类构造方法:使用super调用父类构造方法
    public Car(String brand, int year, int doorCount) {
        super(brand, year);  // 必须首先调用父类构造方法
        this.doorCount = doorCount;
    }
    
    // 重写父类方法(方法覆盖)
    @Override
    public void start() {
        System.out.println(brand + " 汽车启动:钥匙转动,引擎轰鸣!");
    }
    
    // 子类特有的方法
    public void openSunroof() {
        System.out.println(brand + " 的天窗已打开");
    }
    
    // 重写显示信息方法,添加子类特有信息
    @Override
    public void displayInfo() {
        super.displayInfo();  // 调用父类方法
        System.out.println("类型:汽车");
        System.out.println("车门数量:" + doorCount);
    }
}

// 子类:摩托车(继承Vehicle)
class Motorcycle extends Vehicle {
    private boolean hasSidecar;
    
    public Motorcycle(String brand, int year, boolean hasSidecar) {
        super(brand, year);
        this.hasSidecar = hasSidecar;
    }
    
    @Override
    public void start() {
        System.out.println(brand + " 摩托车启动:踩下启动杆,引擎咆哮!");
    }
    
    // 摩托车特有方法
    public void doWheelie() {
        System.out.println(brand + " 正在抬头特技!");
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.println("类型:摩托车");
        System.out.println("是否有边车:" + (hasSidecar ? "是" : "否"));
    }
}

// 子类的子类:电动汽车(继承Car)
class ElectricCar extends Car {
    private double batteryCapacity;  // 电池容量(千瓦时)
    
    public ElectricCar(String brand, int year, int doorCount, double batteryCapacity) {
        super(brand, year, doorCount);
        this.batteryCapacity = batteryCapacity;
    }
    
    @Override
    public void start() {
        System.out.println(brand + " 电动汽车启动:无声启动,零排放!");
    }
    
    // 电动汽车特有方法
    public void chargeBattery() {
        System.out.println(brand + " 正在充电,电池容量:" + batteryCapacity + "kWh");
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();  // 调用Car的displayInfo
        System.out.println("动力类型:电动");
        System.out.println("电池容量:" + batteryCapacity + "kWh");
    }
}

2.3 继承的关键点

  1. super关键字:用于访问父类的属性、方法和构造方法

  2. 方法重写(Override) :子类重新实现父类的方法

  3. 访问修饰符

    • private:只有本类能访问
    • protected:本类、子类和同包类能访问
    • public:所有类都能访问
  4. final关键字

    • final类:不能被继承
    • final方法:不能被子类重写
    • final变量:常量,不能被修改

三、多态:灵活多变的"变形金刚"

3.1 什么是多态?

多态(Polymorphism)意为"多种形态"。在Java中,多态允许我们使用父类引用指向子类对象,同一个方法调用会根据实际对象类型产生不同的行为。

3.2 多态的实现示例

java 复制代码
public class PolymorphismDemo {
    public static void main(String[] args) {
        System.out.println("=== 多态示例:几何图形计算 ===\n");
        
        // 使用父类引用指向不同的子类对象
        Shape[] shapes = new Shape[4];
        
        shapes[0] = new Circle(5.0);
        shapes[1] = new Rectangle(4.0, 6.0);
        shapes[2] = new Triangle(3.0, 4.0, 5.0);
        shapes[3] = new Circle(7.0);
        
        // 多态的魅力:同一个方法调用,不同的行为
        double totalArea = 0;
        double totalPerimeter = 0;
        
        for (Shape shape : shapes) {
            System.out.println(shape.getShapeName() + ":");
            System.out.printf("  面积: %.2f\n", shape.calculateArea());
            System.out.printf("  周长: %.2f\n", shape.calculatePerimeter());
            
            totalArea += shape.calculateArea();
            totalPerimeter += shape.calculatePerimeter();
            
            // 检查具体类型并进行特殊处理
            if (shape instanceof Circle) {
                Circle circle = (Circle) shape;  // 向下转型
                System.out.printf("  半径: %.2f\n", circle.getRadius());
            }
            
            System.out.println();
        }
        
        System.out.printf("总面积: %.2f\n", totalArea);
        System.out.printf("总周长: %.2f\n", totalPerimeter);
        
        // 多态在方法参数中的应用
        System.out.println("\n=== 多态在方法参数中的应用 ===");
        displayShapeInfo(shapes[0]);
        displayShapeInfo(shapes[1]);
    }
    
    // 方法接收父类类型参数,可以接受任何子类对象
    public static void displayShapeInfo(Shape shape) {
        System.out.println("形状信息:");
        shape.displayInfo();
        System.out.println();
    }
}

// 抽象类:形状(不能实例化)
abstract class Shape {
    protected String color;
    
    public Shape() {
        this.color = "黑色";
    }
    
    public Shape(String color) {
        this.color = color;
    }
    
    // 抽象方法:子类必须实现
    public abstract double calculateArea();
    public abstract double calculatePerimeter();
    public abstract String getShapeName();
    
    // 具体方法:子类可以继承或重写
    public void displayInfo() {
        System.out.println("形状: " + getShapeName());
        System.out.println("颜色: " + color);
        System.out.printf("面积: %.2f\n", calculateArea());
        System.out.printf("周长: %.2f\n", calculatePerimeter());
    }
    
    // Getter和Setter
    public String getColor() {
        return color;
    }
    
    public void setColor(String color) {
        this.color = color;
    }
}

// 具体类:圆形
class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        super();
        this.radius = radius;
    }
    
    public Circle(double radius, String color) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double calculatePerimeter() {
        return 2 * Math.PI * radius;
    }
    
    @Override
    public String getShapeName() {
        return "圆形";
    }
    
    // Circle特有的方法
    public double getRadius() {
        return radius;
    }
    
    public void setRadius(double radius) {
        if (radius > 0) {
            this.radius = radius;
        }
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.printf("半径: %.2f\n", radius);
        System.out.printf("直径: %.2f\n", 2 * radius);
    }
}

// 具体类:矩形
class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        super("蓝色");
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
    
    @Override
    public double calculatePerimeter() {
        return 2 * (width + height);
    }
    
    @Override
    public String getShapeName() {
        return "矩形";
    }
    
    // Rectangle特有的方法
    public double getWidth() {
        return width;
    }
    
    public double getHeight() {
        return height;
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.printf("宽度: %.2f\n", width);
        System.out.printf("高度: %.2f\n", height);
    }
}

// 具体类:三角形
class Triangle extends Shape {
    private double sideA;
    private double sideB;
    private double sideC;
    
    public Triangle(double a, double b, double c) {
        super("绿色");
        this.sideA = a;
        this.sideB = b;
        this.sideC = c;
    }
    
    @Override
    public double calculateArea() {
        // 使用海伦公式计算三角形面积
        double s = (sideA + sideB + sideC) / 2;
        return Math.sqrt(s * (s - sideA) * (s - sideB) * (s - sideC));
    }
    
    @Override
    public double calculatePerimeter() {
        return sideA + sideB + sideC;
    }
    
    @Override
    public String getShapeName() {
        return "三角形";
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.printf("边长: %.2f, %.2f, %.2f\n", sideA, sideB, sideC);
    }
}

3.3 多态的两种形式

java 复制代码
public class PolymorphismForms {
    public static void main(String[] args) {
        System.out.println("=== 多态的两种形式 ===\n");
        
        // 形式1:编译时多态(方法重载)
        Calculator calc = new Calculator();
        System.out.println("加法重载示例:");
        System.out.println("两个整数相加: " + calc.add(5, 3));
        System.out.println("三个整数相加: " + calc.add(5, 3, 2));
        System.out.println("两个小数相加: " + calc.add(5.5, 3.3));
        System.out.println("整数和小数相加: " + calc.add(5, 3.3));
        
        // 形式2:运行时多态(方法重写)
        System.out.println("\n动物叫声示例:");
        Animal myAnimal;
        
        // 运行时决定调用哪个方法
        myAnimal = new Dog();
        myAnimal.makeSound();  // 输出:汪汪汪!
        
        myAnimal = new Cat();
        myAnimal.makeSound();  // 输出:喵喵喵!
        
        myAnimal = new Bird();
        myAnimal.makeSound();  // 输出:叽叽喳喳!
        
        // 实际应用:工厂模式
        System.out.println("\n=== 工厂模式示例 ===");
        AnimalFactory factory = new AnimalFactory();
        
        Animal animal1 = factory.createAnimal("dog");
        animal1.makeSound();
        
        Animal animal2 = factory.createAnimal("cat");
        animal2.makeSound();
        
        Animal animal3 = factory.createAnimal("bird");
        animal3.makeSound();
    }
}

// 编译时多态:方法重载
class Calculator {
    // 同一个方法名,不同的参数列表
    public int add(int a, int b) {
        return a + b;
    }
    
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
    
    public double add(int a, double b) {
        return a + b;
    }
}

// 运行时多态:方法重写
abstract class Animal {
    public abstract void makeSound();
    
    public void sleep() {
        System.out.println("动物正在睡觉...");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪!");
    }
    
    public void fetch() {
        System.out.println("狗狗叼回了飞盘");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵!");
    }
    
    public void scratch() {
        System.out.println("猫在抓沙发");
    }
}

class Bird extends Animal {
    @Override
    public void makeSound() {
        System.out.println("叽叽喳喳!");
    }
    
    public void fly() {
        System.out.println("鸟在飞翔");
    }
}

// 工厂模式:使用多态创建对象
class AnimalFactory {
    public Animal createAnimal(String type) {
        switch (type.toLowerCase()) {
            case "dog":
                return new Dog();
            case "cat":
                return new Cat();
            case "bird":
                return new Bird();
            default:
                throw new IllegalArgumentException("未知的动物类型: " + type);
        }
    }
}

3.4 多态的优势

  1. 代码灵活性:可以编写更通用的代码
  2. 易于扩展:添加新的子类时,无需修改现有代码
  3. 接口统一:不同对象可以通过统一接口操作
  4. 解耦合:降低模块间的依赖关系

四、三大特性综合实战:员工管理系统

java 复制代码
import java.util.ArrayList;

public class EmployeeManagementSystem {
    public static void main(String[] args) {
        System.out.println("=== 员工管理系统 ===\n");
        
        // 创建公司
        Company company = new Company("科技无限公司");
        
        // 创建不同类型的员工
        Employee manager = new Manager("张经理", 50000, 20000, 10);
        Employee developer = new Developer("王程序员", 30000, "Java", 5);
        Employee sales = new Salesperson("李销售", 25000, 1000000);
        
        // 添加员工到公司
        company.hireEmployee(manager);
        company.hireEmployee(developer);
        company.hireEmployee(sales);
        
        // 临时工
        company.hireEmployee(new Intern("赵实习生", 5000, 6));
        
        // 展示所有员工信息
        company.displayAllEmployees();
        
        // 计算总工资支出
        System.out.println("\n=== 月度工资报告 ===");
        company.calculateMonthlyPayroll();
        
        // 员工工作
        System.out.println("\n=== 员工工作 ===");
        company.makeEmployeesWork();
        
        // 晋升员工
        System.out.println("\n=== 员工晋升 ===");
        company.promoteEmployee("王程序员", "Senior Developer");
        
        // 展示晋升后信息
        company.displayAllEmployees();
    }
}

// 抽象员工类
abstract class Employee {
    protected String name;
    protected double baseSalary;
    protected String employeeId;
    protected static int nextId = 1000;  // 静态变量,用于生成ID
    
    public Employee(String name, double baseSalary) {
        this.name = name;
        this.baseSalary = baseSalary;
        this.employeeId = "EMP" + nextId++;
    }
    
    // 抽象方法:计算工资(不同员工计算方式不同)
    public abstract double calculateSalary();
    
    // 抽象方法:工作(不同员工工作内容不同)
    public abstract void work();
    
    // 具体方法:所有员工共享
    public void attendMeeting() {
        System.out.println(name + " 正在参加会议");
    }
    
    public void takeBreak() {
        System.out.println(name + " 正在休息");
    }
    
    // 显示员工信息
    public void displayInfo() {
        System.out.println("ID: " + employeeId);
        System.out.println("姓名: " + name);
        System.out.println("职位: " + getPosition());
        System.out.printf("基本工资: ¥%.2f\n", baseSalary);
        System.out.printf("实发工资: ¥%.2f\n", calculateSalary());
    }
    
    // 获取职位名称
    public abstract String getPosition();
    
    // Getter方法
    public String getName() {
        return name;
    }
    
    public String getEmployeeId() {
        return employeeId;
    }
    
    // Setter方法
    public void setName(String name) {
        if (name != null && !name.trim().isEmpty()) {
            this.name = name;
        }
    }
}

// 经理类
class Manager extends Employee {
    private double bonus;
    private int teamSize;
    
    public Manager(String name, double baseSalary, double bonus, int teamSize) {
        super(name, baseSalary);
        this.bonus = bonus;
        this.teamSize = teamSize;
    }
    
    @Override
    public double calculateSalary() {
        // 经理工资 = 基本工资 + 奖金
        return baseSalary + bonus;
    }
    
    @Override
    public void work() {
        System.out.println(name + " 经理正在制定项目计划和分配任务");
        System.out.println("管理团队大小: " + teamSize + "人");
    }
    
    @Override
    public String getPosition() {
        return "经理";
    }
    
    // 经理特有方法
    public void conductReview(Employee employee) {
        System.out.println(name + " 正在对员工 " + employee.getName() + " 进行绩效评估");
    }
    
    public void setBonus(double bonus) {
        if (bonus >= 0) {
            this.bonus = bonus;
        }
    }
}

// 开发人员类
class Developer extends Employee {
    private String programmingLanguage;
    private int yearsOfExperience;
    
    public Developer(String name, double baseSalary, String language, int experience) {
        super(name, baseSalary);
        this.programmingLanguage = language;
        this.yearsOfExperience = experience;
    }
    
    @Override
    public double calculateSalary() {
        // 开发人员工资 = 基本工资 + 经验津贴(每年经验+5%)
        double experienceBonus = baseSalary * 0.05 * yearsOfExperience;
        return baseSalary + experienceBonus;
    }
    
    @Override
    public void work() {
        System.out.println(name + " 开发人员正在用 " + programmingLanguage + " 编写代码");
        System.out.println("经验: " + yearsOfExperience + "年");
    }
    
    @Override
    public String getPosition() {
        return "开发人员 (" + programmingLanguage + ")";
    }
    
    // 开发人员特有方法
    public void debugCode() {
        System.out.println(name + " 正在调试代码");
    }
    
    public void attendTechMeeting() {
        System.out.println(name + " 正在参加技术会议");
    }
}

// 销售人员类
class Salesperson extends Employee {
    private double salesAmount;
    
    public Salesperson(String name, double baseSalary, double salesAmount) {
        super(name, baseSalary);
        this.salesAmount = salesAmount;
    }
    
    @Override
    public double calculateSalary() {
        // 销售人员工资 = 基本工资 + 销售提成(销售额的10%)
        double commission = salesAmount * 0.10;
        return baseSalary + commission;
    }
    
    @Override
    public void work() {
        System.out.println(name + " 销售人员正在联系客户,完成销售目标");
        System.out.printf("本月销售额: ¥%.2f\n", salesAmount);
    }
    
    @Override
    public String getPosition() {
        return "销售人员";
    }
    
    // 销售人员特有方法
    public void makeSale(double amount) {
        salesAmount += amount;
        System.out.println(name + " 完成一笔销售: ¥" + amount);
    }
    
    public void attendSalesTraining() {
        System.out.println(name + " 正在参加销售培训");
    }
}

// 实习生类
class Intern extends Employee {
    private int internshipDuration;  // 实习时长(月)
    
    public Intern(String name, double baseSalary, int duration) {
        super(name, baseSalary);
        this.internshipDuration = duration;
    }
    
    @Override
    public double calculateSalary() {
        // 实习生只有基本工资,没有奖金
        return baseSalary;
    }
    
    @Override
    public void work() {
        System.out.println(name + " 实习生正在学习并协助完成简单任务");
        System.out.println("实习时长: " + internshipDuration + "个月");
    }
    
    @Override
    public String getPosition() {
        return "实习生";
    }
    
    // 实习生特有方法
    public void learn() {
        System.out.println(name + " 正在学习新技能");
    }
    
    public void requestMentor() {
        System.out.println(name + " 请求导师指导");
    }
}

// 公司类
class Company {
    private String name;
    private ArrayList<Employee> employees;
    
    public Company(String name) {
        this.name = name;
        this.employees = new ArrayList<>();
    }
    
    // 雇佣员工(多态:可以接收任何Employee子类)
    public void hireEmployee(Employee employee) {
        employees.add(employee);
        System.out.println("已雇佣: " + employee.getName() + " (" + employee.getPosition() + ")");
    }
    
    // 展示所有员工信息
    public void displayAllEmployees() {
        System.out.println("=== " + name + " 员工列表 ===");
        System.out.println("=".repeat(50));
        
        for (Employee emp : employees) {
            emp.displayInfo();
            System.out.println("-".repeat(50));
        }
    }
    
    // 计算月度工资支出
    public void calculateMonthlyPayroll() {
        double total = 0;
        
        for (Employee emp : employees) {
            total += emp.calculateSalary();
        }
        
        System.out.printf("员工总数: %d人\n", employees.size());
        System.out.printf("月度工资总支出: ¥%.2f\n", total);
        
        // 按职位统计
        System.out.println("\n按职位统计:");
        for (Employee emp : employees) {
            System.out.printf("%-20s: ¥%.2f\n", 
                emp.getPosition(), emp.calculateSalary());
        }
    }
    
    // 让所有员工工作(多态:调用各自的工作方法)
    public void makeEmployeesWork() {
        for (Employee emp : employees) {
            System.out.print("> ");
            emp.work();
        }
    }
    
    // 晋升员工
    public void promoteEmployee(String employeeName, String newPosition) {
        for (Employee emp : employees) {
            if (emp.getName().equals(employeeName)) {
                System.out.println(emp.getName() + " 晋升为: " + newPosition);
                
                // 根据晋升调整工资
                if (emp instanceof Developer) {
                    Developer dev = (Developer) emp;
                    System.out.println("工资增加20%");
                    // 实际应用中会有更复杂的逻辑
                } else if (emp instanceof Manager) {
                    Manager mgr = (Manager) emp;
                    System.out.println("奖金增加30%");
                }
                return;
            }
        }
        System.out.println("未找到员工: " + employeeName);
    }
}

五、总结:三大特性的核心要点

🎯 核心要点总结:

  1. 封装(Encapsulation) :把数据和行为包装在类中,隐藏实现细节

    • 使用private保护数据
    • 通过public方法提供访问接口
    • 好处:安全性、易维护、低耦合
  2. 继承(Inheritance) :子类继承父类的属性和方法

    • 使用extends关键字
    • super调用父类构造方法
    • 方法重写(@Override
    • 好处:代码复用、建立层次关系
  3. 多态(Polymorphism) :同一接口,不同实现

    • 编译时多态:方法重载
    • 运行时多态:方法重写
    • 父类引用指向子类对象
    • 好处:灵活性、扩展性、解耦合

💡 实战建议:

  1. 合理设计类层次:不要让继承层次太深(通常不超过3层)
  2. 优先使用组合而不是继承:除非有明显的"is-a"关系
  3. 为扩展而设计:使用抽象类和接口定义契约
  4. 遵守里氏替换原则:子类应该能够替换父类而不影响程序功能
相关推荐
Lucky_Turtle2 小时前
【Springboot】解决PageHelper在实体转Vo下出现total数据问题
java·spring boot·后端
Mr.朱鹏2 小时前
大模型入门学习路径(Java开发者版)下
java·python·学习·微服务·langchain·大模型·llm
期待のcode2 小时前
验证码实现
java·vue.js
老华带你飞2 小时前
志愿者服务管理|基于springboot 志愿者服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
汤姆yu2 小时前
基于springboot的宠物服务管理系统
java·spring boot·后端
鹿角片ljp2 小时前
智能家居控制系统Java实现
java·开发语言·智能家居
猿饵块2 小时前
python--锁
java·jvm·python
Charlie_Byte3 小时前
用 MurmurHash + Base62 生成短链接
java·后端
星辰落满衣3 小时前
股票实时交易数据之Python、Java等多种主流语言实例代码演示通过股票数据接口
java·开发语言·python