本章目标

  • 深入理解面向对象的核心概念
  • 掌握类与对象的关系和设计原则
  • 理解继承、封装、多态的本质和应用
  • 学会正确使用接口和抽象类
  • 掌握对象间关系的设计和实现

2.1 面向对象核心概念

2.1.1 类与对象

类(Class)是对象的模板或蓝图,定义了对象的属性和行为。 对象(Object)是类的实例,具有具体的属性值和可执行的行为。

// 类的定义
public class Car {
    // 属性(状态)
    private String brand;
    private String model;
    private int year;
    private double speed;
    private boolean isRunning;
    
    // 构造方法
    public Car(String brand, String model, int year) {
        this.brand = brand;
        this.model = model;
        this.year = year;
        this.speed = 0.0;
        this.isRunning = false;
    }
    
    // 行为(方法)
    public void start() {
        if (!isRunning) {
            isRunning = true;
            System.out.println(brand + " " + model + " started.");
        }
    }
    
    public void stop() {
        if (isRunning) {
            isRunning = false;
            speed = 0.0;
            System.out.println(brand + " " + model + " stopped.");
        }
    }
    
    public void accelerate(double increment) {
        if (isRunning) {
            speed += increment;
            System.out.println("Speed: " + speed + " km/h");
        } else {
            System.out.println("Car is not running. Start the car first.");
        }
    }
    
    // Getter和Setter方法
    public String getBrand() { return brand; }
    public String getModel() { return model; }
    public int getYear() { return year; }
    public double getSpeed() { return speed; }
    public boolean isRunning() { return isRunning; }
}

// 对象的创建和使用
public class CarDemo {
    public static void main(String[] args) {
        // 创建对象
        Car myCar = new Car("Toyota", "Camry", 2023);
        Car friendCar = new Car("Honda", "Civic", 2022);
        
        // 使用对象
        myCar.start();
        myCar.accelerate(50);
        myCar.accelerate(30);
        myCar.stop();
        
        friendCar.start();
        friendCar.accelerate(60);
        System.out.println(friendCar.getBrand() + " speed: " + friendCar.getSpeed());
    }
}

2.1.2 类的设计原则

1. 高内聚(High Cohesion)

类的内部元素应该紧密相关,共同完成一个明确的功能。

# 低内聚的例子(不好的设计)
class UserManager:
    def __init__(self):
        self.users = []
        self.email_service = EmailService()
        self.file_system = FileSystem()
    
    def add_user(self, user):
        self.users.append(user)
    
    def send_email(self, to, subject, body):  # 与用户管理无关
        self.email_service.send(to, subject, body)
    
    def save_file(self, filename, content):   # 与用户管理无关
        self.file_system.save(filename, content)
    
    def calculate_tax(self, income):          # 与用户管理无关
        return income * 0.2
# 高内聚的重构
class UserManager:
    def __init__(self):
        self.users = []
    
    def add_user(self, user):
        if self.validate_user(user):
            self.users.append(user)
            return True
        return False
    
    def remove_user(self, user_id):
        self.users = [u for u in self.users if u.id != user_id]
    
    def find_user(self, user_id):
        return next((u for u in self.users if u.id == user_id), None)
    
    def validate_user(self, user):
        # 用户验证逻辑
        return user.email and user.name
    
    def get_active_users(self):
        return [u for u in self.users if u.is_active]

class EmailService:
    def send(self, to, subject, body):
        # 邮件发送逻辑
        pass

class TaxCalculator:
    def calculate_tax(self, income):
        return income * 0.2

2. 低耦合(Low Coupling)

类之间的依赖关系应该尽可能少,减少相互影响。

// 高耦合的例子(不好的设计)
class DatabaseConnection {
public:
    void connect() {
        std::cout << "Connecting to MySQL database..." << std::endl;
    }
    
    void disconnect() {
        std::cout << "Disconnecting from MySQL database..." << std::endl;
    }
    
    void executeQuery(const std::string& query) {
        std::cout << "Executing: " << query << std::endl;
    }
};

class UserService {
private:
    DatabaseConnection db;  // 紧耦合到具体的数据库实现
    
public:
    void createUser(const std::string& name, const std::string& email) {
        db.connect();
        std::string query = "INSERT INTO users (name, email) VALUES ('" + 
                           name + "', '" + email + "')";
        db.executeQuery(query);
        db.disconnect();
    }
};
// 低耦合的重构
#include <memory>

class DatabaseInterface {
public:
    virtual ~DatabaseInterface() = default;
    virtual void connect() = 0;
    virtual void disconnect() = 0;
    virtual void executeQuery(const std::string& query) = 0;
};

class MySQLDatabase : public DatabaseInterface {
public:
    void connect() override {
        std::cout << "Connecting to MySQL database..." << std::endl;
    }
    
    void disconnect() override {
        std::cout << "Disconnecting from MySQL database..." << std::endl;
    }
    
    void executeQuery(const std::string& query) override {
        std::cout << "MySQL executing: " << query << std::endl;
    }
};

class PostgreSQLDatabase : public DatabaseInterface {
public:
    void connect() override {
        std::cout << "Connecting to PostgreSQL database..." << std::endl;
    }
    
    void disconnect() override {
        std::cout << "Disconnecting from PostgreSQL database..." << std::endl;
    }
    
    void executeQuery(const std::string& query) override {
        std::cout << "PostgreSQL executing: " << query << std::endl;
    }
};

class UserService {
private:
    std::unique_ptr<DatabaseInterface> db;
    
public:
    UserService(std::unique_ptr<DatabaseInterface> database) 
        : db(std::move(database)) {}
    
    void createUser(const std::string& name, const std::string& email) {
        db->connect();
        std::string query = "INSERT INTO users (name, email) VALUES ('" + 
                           name + "', '" + email + "')";
        db->executeQuery(query);
        db->disconnect();
    }
};

// 使用示例
int main() {
    // 可以轻松切换数据库实现
    auto mysqlService = std::make_unique<UserService>(
        std::make_unique<MySQLDatabase>()
    );
    
    auto postgresService = std::make_unique<UserService>(
        std::make_unique<PostgreSQLDatabase>()
    );
    
    mysqlService->createUser("John", "john@example.com");
    postgresService->createUser("Jane", "jane@example.com");
    
    return 0;
}

2.2 封装(Encapsulation)

2.2.1 封装的概念

封装是将数据和操作数据的方法绑定在一起,并隐藏对象的内部实现细节,只暴露必要的接口。

2.2.2 访问控制

public class BankAccount {
    // 私有属性,外部无法直接访问
    private String accountNumber;
    private double balance;
    private String ownerName;
    private boolean isActive;
    
    // 构造方法
    public BankAccount(String accountNumber, String ownerName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = initialBalance;
        this.isActive = true;
    }
    
    // 公共方法,提供受控的访问
    public boolean deposit(double amount) {
        if (!isActive) {
            System.out.println("Account is inactive");
            return false;
        }
        
        if (amount <= 0) {
            System.out.println("Deposit amount must be positive");
            return false;
        }
        
        balance += amount;
        System.out.println("Deposited: $" + amount + ", New balance: $" + balance);
        return true;
    }
    
    public boolean withdraw(double amount) {
        if (!isActive) {
            System.out.println("Account is inactive");
            return false;
        }
        
        if (amount <= 0) {
            System.out.println("Withdrawal amount must be positive");
            return false;
        }
        
        if (amount > balance) {
            System.out.println("Insufficient funds");
            return false;
        }
        
        balance -= amount;
        System.out.println("Withdrawn: $" + amount + ", New balance: $" + balance);
        return true;
    }
    
    // 只读访问器
    public double getBalance() {
        return isActive ? balance : 0;
    }
    
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public String getOwnerName() {
        return ownerName;
    }
    
    public boolean isActive() {
        return isActive;
    }
    
    // 受控的状态修改
    public void deactivateAccount() {
        isActive = false;
        System.out.println("Account deactivated");
    }
    
    public void activateAccount() {
        isActive = true;
        System.out.println("Account activated");
    }
    
    // 私有辅助方法
    private boolean validateAmount(double amount) {
        return amount > 0;
    }
    
    private void logTransaction(String type, double amount) {
        System.out.println("Transaction: " + type + ", Amount: $" + amount + 
                          ", Time: " + java.time.LocalDateTime.now());
    }
}

2.2.3 属性封装的最佳实践

class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius  # 受保护的属性
    
    @property
    def celsius(self):
        """获取摄氏温度"""
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        """设置摄氏温度,包含验证逻辑"""
        if value < -273.15:
            raise ValueError("Temperature cannot be below absolute zero")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        """获取华氏温度"""
        return (self._celsius * 9/5) + 32
    
    @fahrenheit.setter
    def fahrenheit(self, value):
        """通过华氏温度设置摄氏温度"""
        celsius_value = (value - 32) * 5/9
        self.celsius = celsius_value  # 使用celsius的setter进行验证
    
    @property
    def kelvin(self):
        """获取开尔文温度"""
        return self._celsius + 273.15
    
    @kelvin.setter
    def kelvin(self, value):
        """通过开尔文温度设置摄氏温度"""
        if value < 0:
            raise ValueError("Kelvin temperature cannot be negative")
        self._celsius = value - 273.15
    
    def __str__(self):
        return f"{self._celsius}°C ({self.fahrenheit}°F, {self.kelvin}K)"

# 使用示例
temp = Temperature(25)
print(temp)  # 25°C (77.0°F, 298.15K)

temp.fahrenheit = 100
print(temp)  # 37.77777777777778°C (100.0°F, 310.92777777777775K)

temp.kelvin = 300
print(temp)  # 26.850000000000023°C (80.33000000000004°F, 300.0K)

# 尝试设置无效值
try:
    temp.celsius = -300  # 会抛出异常
except ValueError as e:
    print(f"Error: {e}")

2.3 继承(Inheritance)

2.3.1 继承的基本概念

继承允许一个类(子类)获得另一个类(父类)的属性和方法,实现代码复用和层次化设计。

// 基类(父类)
public abstract class Animal {
    protected String name;
    protected int age;
    protected double weight;
    
    public Animal(String name, int age, double weight) {
        this.name = name;
        this.age = age;
        this.weight = weight;
    }
    
    // 具体方法
    public void eat(String food) {
        System.out.println(name + " is eating " + food);
        weight += 0.1; // 假设每次进食增加0.1kg
    }
    
    public void sleep(int hours) {
        System.out.println(name + " is sleeping for " + hours + " hours");
    }
    
    // 抽象方法,子类必须实现
    public abstract void makeSound();
    public abstract void move();
    
    // Getter方法
    public String getName() { return name; }
    public int getAge() { return age; }
    public double getWeight() { return weight; }
    
    @Override
    public String toString() {
        return getClass().getSimpleName() + "{name='" + name + "', age=" + age + ", weight=" + weight + "}";
    }
}

// 派生类(子类)
public class Dog extends Animal {
    private String breed;
    private boolean isTrained;
    
    public Dog(String name, int age, double weight, String breed) {
        super(name, age, weight);  // 调用父类构造方法
        this.breed = breed;
        this.isTrained = false;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " barks: Woof! Woof!");
    }
    
    @Override
    public void move() {
        System.out.println(name + " runs on four legs");
    }
    
    // 子类特有的方法
    public void fetch(String item) {
        System.out.println(name + " fetches the " + item);
    }
    
    public void train() {
        isTrained = true;
        System.out.println(name + " has been trained");
    }
    
    // 重写父类方法,添加特定行为
    @Override
    public void eat(String food) {
        if (food.equals("chocolate")) {
            System.out.println("Warning: Chocolate is toxic to dogs!");
            return;
        }
        super.eat(food);  // 调用父类方法
        if (isTrained) {
            System.out.println(name + " sits after eating (good dog!)");
        }
    }
    
    public String getBreed() { return breed; }
    public boolean isTrained() { return isTrained; }
}

public class Cat extends Animal {
    private boolean isIndoor;
    private int livesRemaining;
    
    public Cat(String name, int age, double weight, boolean isIndoor) {
        super(name, age, weight);
        this.isIndoor = isIndoor;
        this.livesRemaining = 9;  // 猫有九条命
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " meows: Meow! Meow!");
    }
    
    @Override
    public void move() {
        System.out.println(name + " walks gracefully and can climb");
    }
    
    public void purr() {
        System.out.println(name + " purrs contentedly");
    }
    
    public void hunt() {
        if (!isIndoor) {
            System.out.println(name + " is hunting mice");
        } else {
            System.out.println(name + " is hunting dust bunnies");
        }
    }
    
    @Override
    public void sleep(int hours) {
        super.sleep(hours);
        if (hours > 12) {
            System.out.println(name + " is living the cat life!");
        }
    }
    
    public boolean isIndoor() { return isIndoor; }
    public int getLivesRemaining() { return livesRemaining; }
}

// 使用示例
public class AnimalDemo {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", 3, 25.5, "Golden Retriever");
        Cat cat = new Cat("Whiskers", 2, 4.2, true);
        
        // 多态性:使用父类引用指向子类对象
        Animal[] animals = {dog, cat};
        
        for (Animal animal : animals) {
            System.out.println(animal);
            animal.makeSound();
            animal.move();
            animal.eat("food");
            animal.sleep(8);
            System.out.println();
        }
        
        // 使用子类特有的方法
        dog.fetch("ball");
        dog.train();
        dog.eat("treats");
        
        cat.purr();
        cat.hunt();
        cat.sleep(16);
    }
}

2.3.2 继承的类型

1. 单继承 vs 多继承

# Python支持多继承
class Flyable:
    def fly(self):
        print("Flying in the sky")
    
    def land(self):
        print("Landing safely")

class Swimmable:
    def swim(self):
        print("Swimming in water")
    
    def dive(self):
        print("Diving underwater")

class Walkable:
    def walk(self):
        print("Walking on ground")
    
    def run(self):
        print("Running fast")

# 多继承:鸭子可以飞、游泳和走路
class Duck(Flyable, Swimmable, Walkable):
    def __init__(self, name):
        self.name = name
    
    def quack(self):
        print(f"{self.name} says: Quack!")
    
    # 可以重写继承的方法
    def fly(self):
        print(f"{self.name} flies with webbed feet tucked")

# 企鹅只能游泳和走路
class Penguin(Swimmable, Walkable):
    def __init__(self, name):
        self.name = name
    
    def slide(self):
        print(f"{self.name} slides on ice")
    
    # 重写游泳方法
    def swim(self):
        print(f"{self.name} swims like a torpedo")

# 使用示例
duck = Duck("Donald")
duck.quack()
duck.fly()
duck.swim()
duck.walk()

penguin = Penguin("Pingu")
penguin.swim()
penguin.walk()
penguin.slide()
# penguin.fly()  # 这会报错,因为企鹅不会飞

2. 方法解析顺序(MRO)

class A:
    def method(self):
        print("A.method")

class B(A):
    def method(self):
        print("B.method")
        super().method()

class C(A):
    def method(self):
        print("C.method")
        super().method()

class D(B, C):
    def method(self):
        print("D.method")
        super().method()

# 查看方法解析顺序
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

d = D()
d.method()
# 输出:
# D.method
# B.method
# C.method
# A.method

2.3.3 继承的最佳实践

1. 优先使用组合而非继承

// 不好的继承设计
class Employee {
    protected String name;
    protected double salary;
    
    public void work() {
        System.out.println(name + " is working");
    }
}

class Manager extends Employee {
    private List<Employee> subordinates;
    
    public void manage() {
        System.out.println(name + " is managing");
    }
}

class Developer extends Employee {
    private String programmingLanguage;
    
    public void code() {
        System.out.println(name + " is coding in " + programmingLanguage);
    }
}

// 问题:如果需要一个既是Manager又是Developer的角色怎么办?
// Java不支持多继承,这种设计就有问题了
// 更好的组合设计
class Employee {
    private String name;
    private double salary;
    private List<Role> roles;
    
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
        this.roles = new ArrayList<>();
    }
    
    public void addRole(Role role) {
        roles.add(role);
    }
    
    public void performDuties() {
        System.out.println(name + " is performing duties:");
        for (Role role : roles) {
            role.performDuty();
        }
    }
    
    // Getters and setters
    public String getName() { return name; }
    public double getSalary() { return salary; }
}

interface Role {
    void performDuty();
}

class ManagerRole implements Role {
    private List<Employee> subordinates;
    
    public ManagerRole() {
        this.subordinates = new ArrayList<>();
    }
    
    @Override
    public void performDuty() {
        System.out.println("Managing team of " + subordinates.size() + " people");
    }
    
    public void addSubordinate(Employee employee) {
        subordinates.add(employee);
    }
}

class DeveloperRole implements Role {
    private String programmingLanguage;
    
    public DeveloperRole(String language) {
        this.programmingLanguage = language;
    }
    
    @Override
    public void performDuty() {
        System.out.println("Coding in " + programmingLanguage);
    }
}

class ArchitectRole implements Role {
    @Override
    public void performDuty() {
        System.out.println("Designing system architecture");
    }
}

// 使用示例
public class EmployeeDemo {
    public static void main(String[] args) {
        Employee john = new Employee("John", 80000);
        
        // John既是管理者又是开发者
        john.addRole(new ManagerRole());
        john.addRole(new DeveloperRole("Java"));
        john.addRole(new ArchitectRole());
        
        john.performDuties();
        
        Employee jane = new Employee("Jane", 70000);
        jane.addRole(new DeveloperRole("Python"));
        
        jane.performDuties();
    }
}

2.4 多态(Polymorphism)

2.4.1 多态的概念

多态允许不同类的对象对同一消息做出不同的响应,实现”一个接口,多种实现”。

2.4.2 运行时多态(动态多态)

#include <iostream>
#include <vector>
#include <memory>

// 基类
class Shape {
protected:
    std::string color;
    
public:
    Shape(const std::string& color) : color(color) {}
    
    // 虚函数实现多态
    virtual double getArea() const = 0;
    virtual double getPerimeter() const = 0;
    virtual void draw() const {
        std::cout << "Drawing a " << color << " shape" << std::endl;
    }
    
    // 虚析构函数
    virtual ~Shape() = default;
    
    std::string getColor() const { return color; }
};

// 派生类
class Circle : public Shape {
private:
    double radius;
    
public:
    Circle(const std::string& color, double radius) 
        : Shape(color), radius(radius) {}
    
    double getArea() const override {
        return 3.14159 * radius * radius;
    }
    
    double getPerimeter() const override {
        return 2 * 3.14159 * radius;
    }
    
    void draw() const override {
        std::cout << "Drawing a " << color << " circle with radius " << radius << std::endl;
    }
    
    double getRadius() const { return radius; }
};

class Rectangle : public Shape {
private:
    double width, height;
    
public:
    Rectangle(const std::string& color, double width, double height)
        : Shape(color), width(width), height(height) {}
    
    double getArea() const override {
        return width * height;
    }
    
    double getPerimeter() const override {
        return 2 * (width + height);
    }
    
    void draw() const override {
        std::cout << "Drawing a " << color << " rectangle (" << width << "x" << height << ")" << std::endl;
    }
    
    double getWidth() const { return width; }
    double getHeight() const { return height; }
};

class Triangle : public Shape {
private:
    double side1, side2, side3;
    
public:
    Triangle(const std::string& color, double s1, double s2, double s3)
        : Shape(color), side1(s1), side2(s2), side3(s3) {}
    
    double getArea() const override {
        // 使用海伦公式
        double s = (side1 + side2 + side3) / 2;
        return std::sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
    
    double getPerimeter() const override {
        return side1 + side2 + side3;
    }
    
    void draw() const override {
        std::cout << "Drawing a " << color << " triangle (" << side1 << ", " 
                  << side2 << ", " << side3 << ")" << std::endl;
    }
};

// 多态函数
void printShapeInfo(const Shape& shape) {
    shape.draw();
    std::cout << "Area: " << shape.getArea() << std::endl;
    std::cout << "Perimeter: " << shape.getPerimeter() << std::endl;
    std::cout << "Color: " << shape.getColor() << std::endl;
    std::cout << "---" << std::endl;
}

double calculateTotalArea(const std::vector<std::unique_ptr<Shape>>& shapes) {
    double total = 0;
    for (const auto& shape : shapes) {
        total += shape->getArea();
    }
    return total;
}

int main() {
    // 创建不同类型的形状
    std::vector<std::unique_ptr<Shape>> shapes;
    shapes.push_back(std::make_unique<Circle>("red", 5.0));
    shapes.push_back(std::make_unique<Rectangle>("blue", 4.0, 6.0));
    shapes.push_back(std::make_unique<Triangle>("green", 3.0, 4.0, 5.0));
    
    // 多态调用
    for (const auto& shape : shapes) {
        printShapeInfo(*shape);
    }
    
    // 计算总面积
    double totalArea = calculateTotalArea(shapes);
    std::cout << "Total area of all shapes: " << totalArea << std::endl;
    
    return 0;
}

2.4.3 编译时多态(静态多态)

1. 函数重载

public class Calculator {
    // 方法重载:相同方法名,不同参数
    public int add(int a, int b) {
        System.out.println("Adding two integers");
        return a + b;
    }
    
    public double add(double a, double b) {
        System.out.println("Adding two doubles");
        return a + b;
    }
    
    public int add(int a, int b, int c) {
        System.out.println("Adding three integers");
        return a + b + c;
    }
    
    public String add(String a, String b) {
        System.out.println("Concatenating two strings");
        return a + b;
    }
    
    // 可变参数
    public int add(int... numbers) {
        System.out.println("Adding variable number of integers");
        int sum = 0;
        for (int num : numbers) {
            sum += num;
        }
        return sum;
    }
    
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        
        System.out.println(calc.add(5, 3));           // 调用add(int, int)
        System.out.println(calc.add(5.5, 3.2));       // 调用add(double, double)
        System.out.println(calc.add(1, 2, 3));        // 调用add(int, int, int)
        System.out.println(calc.add("Hello", "World")); // 调用add(String, String)
        System.out.println(calc.add(1, 2, 3, 4, 5));  // 调用add(int...)
    }
}

2. 泛型(模板)

#include <iostream>
#include <vector>
#include <string>

// 函数模板
template<typename T>
T findMax(const std::vector<T>& vec) {
    if (vec.empty()) {
        throw std::invalid_argument("Vector is empty");
    }
    
    T max = vec[0];
    for (const T& element : vec) {
        if (element > max) {
            max = element;
        }
    }
    return max;
}

// 类模板
template<typename T>
class Stack {
private:
    std::vector<T> elements;
    
public:
    void push(const T& element) {
        elements.push_back(element);
    }
    
    T pop() {
        if (elements.empty()) {
            throw std::runtime_error("Stack is empty");
        }
        T top = elements.back();
        elements.pop_back();
        return top;
    }
    
    const T& top() const {
        if (elements.empty()) {
            throw std::runtime_error("Stack is empty");
        }
        return elements.back();
    }
    
    bool empty() const {
        return elements.empty();
    }
    
    size_t size() const {
        return elements.size();
    }
};

// 模板特化
template<>
class Stack<bool> {
private:
    std::vector<char> elements;  // 使用char而不是bool来避免vector<bool>的问题
    
public:
    void push(bool element) {
        elements.push_back(element ? 1 : 0);
    }
    
    bool pop() {
        if (elements.empty()) {
            throw std::runtime_error("Stack is empty");
        }
        char top = elements.back();
        elements.pop_back();
        return top != 0;
    }
    
    bool top() const {
        if (elements.empty()) {
            throw std::runtime_error("Stack is empty");
        }
        return elements.back() != 0;
    }
    
    bool empty() const {
        return elements.empty();
    }
    
    size_t size() const {
        return elements.size();
    }
};

int main() {
    // 使用函数模板
    std::vector<int> intVec = {1, 5, 3, 9, 2};
    std::vector<std::string> stringVec = {"apple", "banana", "cherry"};
    
    std::cout << "Max int: " << findMax(intVec) << std::endl;
    std::cout << "Max string: " << findMax(stringVec) << std::endl;
    
    // 使用类模板
    Stack<int> intStack;
    intStack.push(10);
    intStack.push(20);
    intStack.push(30);
    
    while (!intStack.empty()) {
        std::cout << "Popped: " << intStack.pop() << std::endl;
    }
    
    Stack<std::string> stringStack;
    stringStack.push("first");
    stringStack.push("second");
    stringStack.push("third");
    
    while (!stringStack.empty()) {
        std::cout << "Popped: " << stringStack.pop() << std::endl;
    }
    
    // 使用特化的bool栈
    Stack<bool> boolStack;
    boolStack.push(true);
    boolStack.push(false);
    boolStack.push(true);
    
    while (!boolStack.empty()) {
        std::cout << "Popped: " << (boolStack.pop() ? "true" : "false") << std::endl;
    }
    
    return 0;
}

2.5 接口和抽象类

2.5.1 接口(Interface)

接口定义了类必须实现的方法契约,但不提供实现。

// 接口定义
public interface Drawable {
    // 接口中的方法默认是public abstract
    void draw();
    void setColor(String color);
    String getColor();
    
    // Java 8+支持默认方法
    default void highlight() {
        System.out.println("Highlighting the drawable object");
    }
    
    // Java 8+支持静态方法
    static void printInfo() {
        System.out.println("This is a drawable interface");
    }
    
    // 接口中的常量默认是public static final
    String DEFAULT_COLOR = "BLACK";
}

public interface Resizable {
    void resize(double factor);
    double getArea();
    
    default void doubleSize() {
        resize(2.0);
    }
}

// 实现多个接口
public class Circle implements Drawable, Resizable {
    private double radius;
    private String color;
    private double x, y;  // 圆心坐标
    
    public Circle(double radius, double x, double y) {
        this.radius = radius;
        this.x = x;
        this.y = y;
        this.color = Drawable.DEFAULT_COLOR;
    }
    
    // 实现Drawable接口
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " circle at (" + x + ", " + y + ") with radius " + radius);
    }
    
    @Override
    public void setColor(String color) {
        this.color = color;
    }
    
    @Override
    public String getColor() {
        return color;
    }
    
    // 实现Resizable接口
    @Override
    public void resize(double factor) {
        if (factor > 0) {
            radius *= factor;
            System.out.println("Circle resized by factor " + factor + ", new radius: " + radius);
        }
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    // 圆特有的方法
    public double getRadius() {
        return radius;
    }
    
    public void move(double newX, double newY) {
        this.x = newX;
        this.y = newY;
        System.out.println("Circle moved to (" + x + ", " + y + ")");
    }
}

public class Rectangle implements Drawable, Resizable {
    private double width, height;
    private String color;
    private double x, y;
    
    public Rectangle(double width, double height, double x, double y) {
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
        this.color = Drawable.DEFAULT_COLOR;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " rectangle at (" + x + ", " + y + ") with size " + width + "x" + height);
    }
    
    @Override
    public void setColor(String color) {
        this.color = color;
    }
    
    @Override
    public String getColor() {
        return color;
    }
    
    @Override
    public void resize(double factor) {
        if (factor > 0) {
            width *= factor;
            height *= factor;
            System.out.println("Rectangle resized by factor " + factor + ", new size: " + width + "x" + height);
        }
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    public double getWidth() { return width; }
    public double getHeight() { return height; }
}

// 使用接口的示例
public class InterfaceDemo {
    public static void main(String[] args) {
        // 多态:使用接口引用
        Drawable[] drawables = {
            new Circle(5.0, 10, 20),
            new Rectangle(4.0, 6.0, 30, 40)
        };
        
        // 绘制所有图形
        for (Drawable drawable : drawables) {
            drawable.setColor("RED");
            drawable.draw();
            drawable.highlight();  // 使用默认方法
        }
        
        // 调用静态方法
        Drawable.printInfo();
        
        // 调整大小
        Resizable[] resizables = {
            new Circle(3.0, 0, 0),
            new Rectangle(2.0, 3.0, 0, 0)
        };
        
        for (Resizable resizable : resizables) {
            System.out.println("Original area: " + resizable.getArea());
            resizable.doubleSize();  // 使用默认方法
            System.out.println("New area: " + resizable.getArea());
        }
    }
}

2.5.2 抽象类(Abstract Class)

抽象类可以包含抽象方法和具体方法,提供部分实现。

from abc import ABC, abstractmethod
import math

# 抽象基类
class Vehicle(ABC):
    def __init__(self, brand, model, year):
        self.brand = brand
        self.model = model
        self.year = year
        self.is_running = False
        self.fuel_level = 100  # 百分比
    
    # 抽象方法,子类必须实现
    @abstractmethod
    def start_engine(self):
        pass
    
    @abstractmethod
    def stop_engine(self):
        pass
    
    @abstractmethod
    def get_max_speed(self):
        pass
    
    @abstractmethod
    def get_fuel_efficiency(self):
        pass
    
    # 具体方法,子类可以直接使用或重写
    def honk(self):
        print(f"{self.brand} {self.model} honks: Beep! Beep!")
    
    def check_fuel(self):
        if self.fuel_level < 10:
            print("Warning: Low fuel!")
        return self.fuel_level
    
    def refuel(self, amount):
        self.fuel_level = min(100, self.fuel_level + amount)
        print(f"Refueled. Current fuel level: {self.fuel_level}%")
    
    def drive(self, distance):
        if not self.is_running:
            print("Start the engine first!")
            return False
        
        fuel_needed = distance / self.get_fuel_efficiency()
        if fuel_needed > self.fuel_level:
            print("Not enough fuel for this trip!")
            return False
        
        self.fuel_level -= fuel_needed
        print(f"Drove {distance} km. Remaining fuel: {self.fuel_level:.1f}%")
        return True
    
    def get_info(self):
        return f"{self.year} {self.brand} {self.model}"
    
    def __str__(self):
        status = "Running" if self.is_running else "Stopped"
        return f"{self.get_info()} - Status: {status}, Fuel: {self.fuel_level}%"

# 具体子类
class Car(Vehicle):
    def __init__(self, brand, model, year, num_doors=4):
        super().__init__(brand, model, year)
        self.num_doors = num_doors
        self.max_speed = 180  # km/h
        self.fuel_efficiency = 15  # km per liter
    
    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"{self.get_info()} engine started with a gentle purr")
        else:
            print("Engine is already running")
    
    def stop_engine(self):
        if self.is_running:
            self.is_running = False
            print(f"{self.get_info()} engine stopped")
        else:
            print("Engine is already stopped")
    
    def get_max_speed(self):
        return self.max_speed
    
    def get_fuel_efficiency(self):
        return self.fuel_efficiency
    
    def open_trunk(self):
        print(f"{self.get_info()} trunk opened")
    
    def lock_doors(self):
        print(f"All {self.num_doors} doors locked")

class Motorcycle(Vehicle):
    def __init__(self, brand, model, year, engine_size):
        super().__init__(brand, model, year)
        self.engine_size = engine_size  # cc
        self.max_speed = 200
        self.fuel_efficiency = 25
    
    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"{self.get_info()} engine started with a loud roar!")
        else:
            print("Engine is already running")
    
    def stop_engine(self):
        if self.is_running:
            self.is_running = False
            print(f"{self.get_info()} engine stopped")
        else:
            print("Engine is already stopped")
    
    def get_max_speed(self):
        return self.max_speed
    
    def get_fuel_efficiency(self):
        return self.fuel_efficiency
    
    def wheelie(self):
        if self.is_running:
            print(f"{self.get_info()} performs a wheelie!")
        else:
            print("Start the engine first to perform a wheelie!")
    
    # 重写父类方法
    def honk(self):
        print(f"{self.brand} {self.model} revs: Vroom! Vroom!")

class Truck(Vehicle):
    def __init__(self, brand, model, year, cargo_capacity):
        super().__init__(brand, model, year)
        self.cargo_capacity = cargo_capacity  # tons
        self.current_load = 0
        self.max_speed = 120
        self.fuel_efficiency = 8
    
    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"{self.get_info()} diesel engine started with a rumble")
        else:
            print("Engine is already running")
    
    def stop_engine(self):
        if self.is_running:
            self.is_running = False
            print(f"{self.get_info()} engine stopped")
        else:
            print("Engine is already stopped")
    
    def get_max_speed(self):
        # 载重影响最大速度
        load_factor = self.current_load / self.cargo_capacity
        return self.max_speed * (1 - load_factor * 0.3)
    
    def get_fuel_efficiency(self):
        # 载重影响油耗
        load_factor = self.current_load / self.cargo_capacity
        return self.fuel_efficiency * (1 - load_factor * 0.4)
    
    def load_cargo(self, weight):
        if self.current_load + weight <= self.cargo_capacity:
            self.current_load += weight
            print(f"Loaded {weight} tons. Current load: {self.current_load}/{self.cargo_capacity} tons")
        else:
            print(f"Cannot load {weight} tons. Exceeds capacity!")
    
    def unload_cargo(self, weight):
        if weight <= self.current_load:
            self.current_load -= weight
            print(f"Unloaded {weight} tons. Current load: {self.current_load}/{self.cargo_capacity} tons")
        else:
            print(f"Cannot unload {weight} tons. Not enough cargo!")

# 使用示例
def main():
    # 创建不同类型的车辆
    vehicles = [
        Car("Toyota", "Camry", 2023),
        Motorcycle("Harley-Davidson", "Street 750", 2022, 750),
        Truck("Volvo", "FH16", 2021, 40)
    ]
    
    print("=== Vehicle Information ===")
    for vehicle in vehicles:
        print(vehicle)
        print(f"Max Speed: {vehicle.get_max_speed()} km/h")
        print(f"Fuel Efficiency: {vehicle.get_fuel_efficiency()} km/L")
        print()
    
    print("=== Starting Engines ===")
    for vehicle in vehicles:
        vehicle.start_engine()
        vehicle.honk()
    
    print("\n=== Driving Test ===")
    car = vehicles[0]
    motorcycle = vehicles[1]
    truck = vehicles[2]
    
    # 汽车测试
    car.drive(100)
    car.lock_doors()
    car.open_trunk()
    
    # 摩托车测试
    motorcycle.drive(150)
    motorcycle.wheelie()
    
    # 卡车测试
    truck.load_cargo(20)
    truck.drive(200)
    print(f"Truck max speed with load: {truck.get_max_speed():.1f} km/h")
    print(f"Truck fuel efficiency with load: {truck.get_fuel_efficiency():.1f} km/L")
    
    print("\n=== Final Status ===")
    for vehicle in vehicles:
        print(vehicle)
        vehicle.check_fuel()
        vehicle.stop_engine()

if __name__ == "__main__":
    main()

2.5.3 接口 vs 抽象类

特性 接口 抽象类
多重继承 支持 不支持(大多数语言)
方法实现 只能有默认方法(Java 8+) 可以有具体方法
属性 只能有常量 可以有实例变量
构造方法 不能有 可以有
访问修饰符 方法默认public 可以有各种访问级别
设计目的 定义契约 提供通用实现

2.6 对象间关系

2.6.1 关联(Association)

关联表示两个类之间的一般性连接。

// 关联关系示例
public class Student {
    private String name;
    private String studentId;
    private List<Course> enrolledCourses;
    
    public Student(String name, String studentId) {
        this.name = name;
        this.studentId = studentId;
        this.enrolledCourses = new ArrayList<>();
    }
    
    public void enrollInCourse(Course course) {
        if (!enrolledCourses.contains(course)) {
            enrolledCourses.add(course);
            course.addStudent(this);  // 双向关联
        }
    }
    
    public void dropCourse(Course course) {
        if (enrolledCourses.contains(course)) {
            enrolledCourses.remove(course);
            course.removeStudent(this);
        }
    }
    
    // Getters
    public String getName() { return name; }
    public String getStudentId() { return studentId; }
    public List<Course> getEnrolledCourses() { return new ArrayList<>(enrolledCourses); }
}

public class Course {
    private String courseName;
    private String courseCode;
    private List<Student> enrolledStudents;
    private int maxCapacity;
    
    public Course(String courseName, String courseCode, int maxCapacity) {
        this.courseName = courseName;
        this.courseCode = courseCode;
        this.maxCapacity = maxCapacity;
        this.enrolledStudents = new ArrayList<>();
    }
    
    public boolean addStudent(Student student) {
        if (enrolledStudents.size() < maxCapacity && !enrolledStudents.contains(student)) {
            enrolledStudents.add(student);
            return true;
        }
        return false;
    }
    
    public void removeStudent(Student student) {
        enrolledStudents.remove(student);
    }
    
    // Getters
    public String getCourseName() { return courseName; }
    public String getCourseCode() { return courseCode; }
    public List<Student> getEnrolledStudents() { return new ArrayList<>(enrolledStudents); }
    public int getCurrentEnrollment() { return enrolledStudents.size(); }
    public int getMaxCapacity() { return maxCapacity; }
}

2.6.2 聚合(Aggregation)

聚合是一种特殊的关联,表示”has-a”关系,部分可以独立于整体存在。

// 聚合关系示例
public class Department {
    private String name;
    private List<Employee> employees;
    private Employee manager;
    
    public Department(String name) {
        this.name = name;
        this.employees = new ArrayList<>();
    }
    
    public void addEmployee(Employee employee) {
        if (!employees.contains(employee)) {
            employees.add(employee);
            employee.setDepartment(this);
        }
    }
    
    public void removeEmployee(Employee employee) {
        if (employees.contains(employee)) {
            employees.remove(employee);
            employee.setDepartment(null);  // 员工可以独立存在
        }
    }
    
    public void setManager(Employee manager) {
        if (employees.contains(manager)) {
            this.manager = manager;
        }
    }
    
    // Getters
    public String getName() { return name; }
    public List<Employee> getEmployees() { return new ArrayList<>(employees); }
    public Employee getManager() { return manager; }
}

public class Employee {
    private String name;
    private String employeeId;
    private Department department;  // 员工属于某个部门,但可以独立存在
    
    public Employee(String name, String employeeId) {
        this.name = name;
        this.employeeId = employeeId;
    }
    
    public void setDepartment(Department department) {
        this.department = department;
    }
    
    // Getters
    public String getName() { return name; }
    public String getEmployeeId() { return employeeId; }
    public Department getDepartment() { return department; }
}

2.6.3 组合(Composition)

组合是一种强聚合,表示”part-of”关系,部分不能独立于整体存在。

// 组合关系示例
public class House {
    private String address;
    private List<Room> rooms;
    private Roof roof;
    private Foundation foundation;
    
    public House(String address) {
        this.address = address;
        this.rooms = new ArrayList<>();
        // 房子创建时,屋顶和地基也被创建(强依赖)
        this.roof = new Roof("Tile Roof");
        this.foundation = new Foundation("Concrete Foundation");
    }
    
    public void addRoom(String roomType, double area) {
        Room room = new Room(roomType, area);  // 房间属于房子,不能独立存在
        rooms.add(room);
    }
    
    public void removeRoom(Room room) {
        rooms.remove(room);
        // 房间被移除后就不存在了(组合关系)
    }
    
    public double getTotalArea() {
        return rooms.stream().mapToDouble(Room::getArea).sum();
    }
    
    // Getters
    public String getAddress() { return address; }
    public List<Room> getRooms() { return new ArrayList<>(rooms); }
    public Roof getRoof() { return roof; }
    public Foundation getFoundation() { return foundation; }
    
    @Override
    public String toString() {
        return "House at " + address + " with " + rooms.size() + " rooms";
    }
}

// 房间类 - 强依赖于房子
class Room {
    private String type;
    private double area;
    
    public Room(String type, double area) {
        this.type = type;
        this.area = area;
    }
    
    public String getType() { return type; }
    public double getArea() { return area; }
    
    @Override
    public String toString() {
        return type + " (" + area + " sq.m)";
    }
}

class Roof {
    private String material;
    
    public Roof(String material) {
        this.material = material;
    }
    
    public String getMaterial() { return material; }
}

class Foundation {
    private String type;
    
    public Foundation(String type) {
        this.type = type;
    }
    
    public String getType() { return type; }
}

// 使用示例
public class CompositionDemo {
    public static void main(String[] args) {
        House house = new House("123 Main Street");
        
        house.addRoom("Living Room", 25.0);
        house.addRoom("Kitchen", 15.0);
        house.addRoom("Bedroom", 20.0);
        house.addRoom("Bathroom", 8.0);
        
        System.out.println(house);
        System.out.println("Total area: " + house.getTotalArea() + " sq.m");
        System.out.println("Roof: " + house.getRoof().getMaterial());
        System.out.println("Foundation: " + house.getFoundation().getType());
        
        // 当房子被销毁时,所有房间、屋顶、地基也会被销毁
    }
}

2.6.4 依赖(Dependency)

依赖是最弱的关系,表示一个类使用另一个类。

// 依赖关系示例
public class EmailService {
    public void sendEmail(String to, String subject, String body) {
        System.out.println("Sending email to: " + to);
        System.out.println("Subject: " + subject);
        System.out.println("Body: " + body);
    }
}

public class SMSService {
    public void sendSMS(String phoneNumber, String message) {
        System.out.println("Sending SMS to: " + phoneNumber);
        System.out.println("Message: " + message);
    }
}

public class NotificationManager {
    // 依赖关系:NotificationManager使用EmailService和SMSService
    // 但不持有它们的引用
    
    public void sendNotification(String type, String recipient, String message) {
        switch (type.toLowerCase()) {
            case "email":
                EmailService emailService = new EmailService();  // 临时依赖
                emailService.sendEmail(recipient, "Notification", message);
                break;
            case "sms":
                SMSService smsService = new SMSService();  // 临时依赖
                smsService.sendSMS(recipient, message);
                break;
            default:
                System.out.println("Unknown notification type: " + type);
        }
    }
    
    // 通过参数依赖
    public void sendEmailNotification(EmailService emailService, String to, String message) {
        emailService.sendEmail(to, "Alert", message);
    }
}

2.6.5 关系总结

# 对象关系总结示例
class University:
    """大学类 - 展示各种对象关系"""
    
    def __init__(self, name):
        self.name = name
        self.departments = []  # 聚合:大学有多个系
        self.campus = Campus(name + " Campus")  # 组合:校园属于大学
        self.library = Library(name + " Library")  # 组合:图书馆属于大学
    
    def add_department(self, department):
        """聚合关系:系可以独立存在"""
        self.departments.append(department)
        department.university = self
    
    def remove_department(self, department):
        """移除系,但系可以独立存在"""
        if department in self.departments:
            self.departments.remove(department)
            department.university = None
    
    def organize_event(self, event_manager):
        """依赖关系:临时使用事件管理器"""
        event_manager.organize("University Open Day", self.campus)

class Department:
    """系类"""
    
    def __init__(self, name):
        self.name = name
        self.university = None  # 聚合:属于大学但可独立存在
        self.professors = []  # 关联:教授与系的关系
        self.courses = []  # 聚合:课程属于系
    
    def hire_professor(self, professor):
        """关联关系:教授与系关联"""
        self.professors.append(professor)
        professor.departments.append(self)
    
    def add_course(self, course):
        """聚合关系:课程属于系"""
        self.courses.append(course)
        course.department = self

class Professor:
    """教授类"""
    
    def __init__(self, name, specialization):
        self.name = name
        self.specialization = specialization
        self.departments = []  # 关联:可以在多个系任教
        self.office = Office(f"{name}'s Office")  # 组合:办公室属于教授
    
    def teach_course(self, course, students):
        """依赖关系:临时使用课程和学生"""
        print(f"{self.name} is teaching {course.name} to {len(students)} students")

class Student:
    """学生类"""
    
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
        self.enrolled_courses = []  # 关联:学生选课
        self.transcript = Transcript(student_id)  # 组合:成绩单属于学生
    
    def enroll_in_course(self, course):
        """关联关系:学生与课程关联"""
        self.enrolled_courses.append(course)
        course.students.append(self)

class Course:
    """课程类"""
    
    def __init__(self, name, code, credits):
        self.name = name
        self.code = code
        self.credits = credits
        self.department = None  # 聚合:属于某个系
        self.students = []  # 关联:与学生关联
        self.assignments = []  # 组合:作业属于课程
    
    def add_assignment(self, title, due_date):
        """组合关系:作业属于课程"""
        assignment = Assignment(title, due_date)
        self.assignments.append(assignment)
        return assignment

class Campus:
    """校园类 - 组合关系"""
    
    def __init__(self, name):
        self.name = name
        self.buildings = []  # 组合:建筑属于校园
    
    def add_building(self, building_name, building_type):
        building = Building(building_name, building_type)
        self.buildings.append(building)
        return building

class Library:
    """图书馆类 - 组合关系"""
    
    def __init__(self, name):
        self.name = name
        self.books = []  # 组合:图书属于图书馆
    
    def add_book(self, title, author):
        book = Book(title, author)
        self.books.append(book)
        return book

class Office:
    """办公室类 - 组合关系"""
    
    def __init__(self, room_number):
        self.room_number = room_number
        self.equipment = []  # 组合:设备属于办公室

class Transcript:
    """成绩单类 - 组合关系"""
    
    def __init__(self, student_id):
        self.student_id = student_id
        self.grades = []  # 组合:成绩属于成绩单

class Assignment:
    """作业类 - 组合关系"""
    
    def __init__(self, title, due_date):
        self.title = title
        self.due_date = due_date

class Building:
    """建筑类 - 组合关系"""
    
    def __init__(self, name, building_type):
        self.name = name
        self.type = building_type

class Book:
    """图书类 - 组合关系"""
    
    def __init__(self, title, author):
        self.title = title
        self.author = author

class EventManager:
    """事件管理器 - 依赖关系"""
    
    def organize(self, event_name, venue):
        print(f"Organizing {event_name} at {venue.name}")

# 使用示例
def main():
    # 创建大学
    university = University("Tech University")
    
    # 创建系(聚合关系)
    cs_dept = Department("Computer Science")
    math_dept = Department("Mathematics")
    
    university.add_department(cs_dept)
    university.add_department(math_dept)
    
    # 创建教授(关联关系)
    prof_smith = Professor("Dr. Smith", "Algorithms")
    prof_jones = Professor("Dr. Jones", "Calculus")
    
    cs_dept.hire_professor(prof_smith)
    math_dept.hire_professor(prof_jones)
    
    # 创建课程(聚合关系)
    algo_course = Course("Data Structures and Algorithms", "CS301", 3)
    calc_course = Course("Calculus I", "MATH101", 4)
    
    cs_dept.add_course(algo_course)
    math_dept.add_course(calc_course)
    
    # 创建学生(关联关系)
    student1 = Student("Alice", "S001")
    student2 = Student("Bob", "S002")
    
    student1.enroll_in_course(algo_course)
    student1.enroll_in_course(calc_course)
    student2.enroll_in_course(algo_course)
    
    # 添加作业(组合关系)
    algo_course.add_assignment("Binary Tree Implementation", "2024-02-15")
    calc_course.add_assignment("Derivative Problems", "2024-02-10")
    
    # 使用事件管理器(依赖关系)
    event_manager = EventManager()
    university.organize_event(event_manager)
    
    # 教授授课(依赖关系)
    prof_smith.teach_course(algo_course, algo_course.students)
    
    print(f"\n{university.name} has {len(university.departments)} departments")
    print(f"CS Department has {len(cs_dept.courses)} courses and {len(cs_dept.professors)} professors")
    print(f"Algorithm course has {len(algo_course.students)} students enrolled")

if __name__ == "__main__":
    main()

2.7 本章总结

2.7.1 核心概念回顾

  1. 类与对象:类是模板,对象是实例
  2. 封装:隐藏内部实现,提供受控访问
  3. 继承:代码复用和层次化设计
  4. 多态:一个接口,多种实现
  5. 接口与抽象类:定义契约和提供部分实现
  6. 对象关系:关联、聚合、组合、依赖

2.7.2 设计原则

  1. 高内聚,低耦合
  2. 优先使用组合而非继承
  3. 面向接口编程
  4. 封装变化点
  5. 遵循SOLID原则

2.7.3 最佳实践

  1. 合理使用访问修饰符
  2. 提供清晰的接口
  3. 避免过深的继承层次
  4. 正确选择对象关系
  5. 编写可测试的代码

2.8 练习题

2.8.1 基础练习

  1. 设计一个图书管理系统,包含图书、读者、借阅记录等类,体现封装、继承、多态的特性。

  2. 实现一个简单的绘图系统,包含不同类型的图形(圆形、矩形、三角形),使用接口定义绘图行为。

  3. 设计一个员工管理系统,区分正式员工、临时员工、管理员等不同类型,使用抽象类和继承。

2.8.2 进阶练习

  1. 设计一个电商系统的核心类结构,包含用户、商品、订单、支付等,正确使用各种对象关系。

  2. 实现一个媒体播放器,支持不同格式的音频和视频文件,使用多态和策略模式。

  3. 设计一个游戏角色系统,包含不同职业、技能、装备等,体现组合优于继承的原则。

2.8.3 思考题

  1. 什么时候应该使用继承?什么时候应该使用组合?

  2. 如何在保持封装性的同时提供灵活的扩展性?

  3. 接口和抽象类在实际项目中如何选择使用?


下一章预告:第03章将深入学习创建型设计模式,包括单例模式、工厂模式、建造者模式等,学习如何优雅地创建对象。