封装案例

wen java案例 2

本文目录导读:

封装案例

  1. 基础封装案例:银行账户
  2. 中级封装案例:员工管理系统
  3. 高级封装案例:订单管理系统
  4. 封装的实践原则
  5. 总结要点

我来为你详细讲解面向对象封装的完整案例,从基础到进阶。

基础封装案例:银行账户

简单属性封装

class BankAccount:
    """银行账户类 - 基础封装"""
    def __init__(self, account_number, owner, balance=0):
        self._account_number = account_number  # 受保护属性
        self._owner = owner                    # 受保护属性
        self._balance = balance                # 私有属性(用_表示)
        self._transactions = []                # 交易记录
    # 获取余额(只读属性)
    def get_balance(self):
        """获取当前余额"""
        return self._balance
    # 存款
    def deposit(self, amount):
        """存款操作"""
        if amount <= 0:
            raise ValueError("存款金额必须大于0")
        self._balance += amount
        self._transactions.append(f"存款: +{amount}元")
        return self._balance
    # 取款
    def withdraw(self, amount):
        """取款操作"""
        if amount <= 0:
            raise ValueError("取款金额必须大于0")
        if amount > self._balance:
            raise ValueError("余额不足")
        self._balance -= amount
        self._transactions.append(f"取款: -{amount}元")
        return self._balance
    # 查看交易记录
    def get_transactions(self):
        """获取交易记录副本,防止外部修改"""
        return self._transactions.copy()
    # 账户信息
    def __str__(self):
        return f"账户: {self._account_number}, 户主: {self._owner}, 余额: {self._balance}元"

使用@property装饰器

class BankAccountV2:
    """使用@property装饰器的银行账户"""
    def __init__(self, account_number, owner, balance=0):
        self._account_number = account_number
        self._owner = owner
        self._balance = balance
        self._transactions = []
    # 只读属性
    @property
    def account_number(self):
        """账户号只读"""
        return self._account_number
    @property
    def owner(self):
        """户主只读"""
        return self._owner
    @property
    def balance(self):
        """余额只读"""
        return self._balance
    @property
    def transactions(self):
        """交易记录返回副本"""
        return self._transactions.copy()
    # 存款(修改方法)
    def deposit(self, amount):
        """存款"""
        self._validate_amount(amount)
        self._balance += amount
        self._transactions.append(("deposit", amount))
    def withdraw(self, amount):
        """取款"""
        self._validate_amount(amount)
        if amount > self._balance:
            raise ValueError("余额不足")
        self._balance -= amount
        self._transactions.append(("withdraw", amount))
    # 私有辅助方法
    def _validate_amount(self, amount):
        """验证金额合法性"""
        if not isinstance(amount, (int, float)):
            raise TypeError("金额必须是数字")
        if amount <= 0:
            raise ValueError("金额必须大于0")
    def __str__(self):
        return f"账户: {self.account_number}, 户主: {self.owner}, 余额: {self.balance}元"

中级封装案例:员工管理系统

from datetime import datetime
import re
class Employee:
    """员工类 - 中级封装"""
    def __init__(self, emp_id, name, department, salary):
        self._id = emp_id                      # 员工ID
        self._name = name                      # 姓名
        self._department = department          # 部门
        self._salary = salary                  # 工资
        self._email = None                     # 邮箱
        self._hire_date = datetime.now()      # 入职日期
        self._performance_scores = []          # 绩效评分
    # 姓名(可读,不可直接修改)
    @property
    def name(self):
        return self._name
    # 部门(可读可修改)
    @property
    def department(self):
        return self._department
    @department.setter
    def department(self, value):
        """设置部门,带验证"""
        if not value or not value.strip():
            raise ValueError("部门不能为空")
        self._department = value.strip()
    # 工资(提供get和set)
    @property
    def salary(self):
        return self._salary
    @salary.setter
    def salary(self, value):
        """设置工资,带验证"""
        if not isinstance(value, (int, float)):
            raise TypeError("工资必须是数字")
        if value < 0:
            raise ValueError("工资不能为负")
        self._salary = value
    # 邮箱(带格式验证)
    @property
    def email(self):
        return self._email
    @email.setter
    def email(self, value):
        """设置邮箱,验证格式"""
        if value and not re.match(r'^[\w\.-]+@[\w\.-]+\.\w+$', value):
            raise ValueError("邮箱格式不正确")
        self._email = value
    # 添加绩效评分
    def add_performance_score(self, score):
        """添加绩效评分"""
        if not isinstance(score, (int, float)):
            raise TypeError("评分必须是数字")
        if not 0 <= score <= 100:
            raise ValueError("评分范围0-100")
        self._performance_scores.append(score)
    # 获取平均绩效
    def get_average_performance(self):
        """获取平均绩效评分"""
        if not self._performance_scores:
            return 0
        return sum(self._performance_scores) / len(self._performance_scores)
    # 获取员工信息
    def get_employee_info(self):
        """获取员工完整信息"""
        return {
            "ID": self._id,
            "姓名": self._name,
            "部门": self._department,
            "工资": self._salary,
            "邮箱": self._email or "未设置",
            "入职日期": self._hire_date.strftime("%Y-%m-%d"),
            "平均绩效": self.get_average_performance()
        }
# 使用示例
emp = Employee("EMP001", "张三", "技术部", 15000)
emp.email = "zhangsan@company.com"
emp.add_performance_score(85)
emp.add_performance_score(92)
emp.add_performance_score(78)
print(emp.get_employee_info())

高级封装案例:订单管理系统

from typing import List, Dict, Optional
from datetime import datetime
import json
class OrderItem:
    """订单项类"""
    def __init__(self, product_id: str, product_name: str, price: float, quantity: int):
        self._product_id = product_id
        self._product_name = product_name
        self._price = price
        self._quantity = quantity
    @property
    def product_id(self):
        return self._product_id
    @property
    def subtotal(self) -> float:
        """计算小计"""
        return self._price * self._quantity
    def to_dict(self) -> Dict:
        """转为字典"""
        return {
            "product_id": self._product_id,
            "product_name": self._product_name,
            "price": self._price,
            "quantity": self._quantity,
            "subtotal": self.subtotal
        }
    def __str__(self):
        return f"{self._product_name} x{self._quantity} = ¥{self.subtotal}"
class Order:
    """订单类 - 高级封装"""
    def __init__(self, order_id: str, customer_name: str):
        self._order_id = order_id
        self._customer_name = customer_name
        self._items: List[OrderItem] = []
        self._status = "pending"  # pending, paid, shipped, completed, cancelled
        self._created_at = datetime.now()
        self._discount_rate = 0.0  # 折扣率,0-1之间
    # 订单状态常量
    STATUS_PENDING = "pending"
    STATUS_PAID = "paid"
    STATUS_SHIPPED = "shipped"
    STATUS_COMPLETED = "completed"
    STATUS_CANCELLED = "cancelled"
    @property
    def order_id(self):
        return self._order_id
    @property
    def status(self):
        return self._status
    @property
    def created_at(self):
        return self._created_at
    @property
    def total_amount(self) -> float:
        """计算订单总额"""
        total = sum(item.subtotal for item in self._items)
        return total * (1 - self._discount_rate)
    def add_item(self, item: OrderItem):
        """添加订单项"""
        if self._status != self.STATUS_PENDING:
            raise ValueError("只有待处理状态的订单可以添加商品")
        self._items.append(item)
    def remove_item(self, product_id: str):
        """移除订单项"""
        if self._status != self.STATUS_PENDING:
            raise ValueError("只有待处理状态的订单可以移除商品")
        self._items = [item for item in self._items if item.product_id != product_id]
    def set_discount(self, rate: float):
        """设置折扣"""
        if not 0 <= rate <= 0.9:
            raise ValueError("折扣率必须在0-0.9之间")
        self._discount_rate = rate
    def update_status(self, new_status: str):
        """更新订单状态"""
        valid_transitions = {
            self.STATUS_PENDING: [self.STATUS_PAID, self.STATUS_CANCELLED],
            self.STATUS_PAID: [self.STATUS_SHIPPED, self.STATUS_CANCELLED],
            self.STATUS_SHIPPED: [self.STATUS_COMPLETED],
            self.STATUS_COMPLETED: [],
            self.STATUS_CANCELLED: []
        }
        if new_status not in valid_transitions.get(self._status, []):
            raise ValueError(f"不能从{self._status}状态转换为{new_status}状态")
        self._status = new_status
    def to_dict(self) -> Dict:
        """转为字典"""
        return {
            "order_id": self._order_id,
            "customer_name": self._customer_name,
            "status": self._status,
            "created_at": self._created_at.isoformat(),
            "items": [item.to_dict() for item in self._items],
            "discount_rate": self._discount_rate,
            "total_amount": self.total_amount
        }
    def save_to_file(self, filepath: str):
        """保存订单到文件"""
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(self.to_dict(), f, ensure_ascii=False, indent=2)
    def __str__(self):
        items_str = "\n".join(str(item) for item in self._items)
        return f"订单号: {self._order_id}\n客户: {self._customer_name}\n状态: {self._status}\n{items_str}\n总额: ¥{self.total_amount}"
# 使用示例
order = Order("ORD-2024-001", "李四")
# 添加订单项
order.add_item(OrderItem("P001", "笔记本电脑", 5999.00, 1))
order.add_item(OrderItem("P002", "无线鼠标", 199.00, 2))
order.add_item(OrderItem("P003", "键盘", 299.00, 1))
# 设置折扣
order.set_discount(0.1)  # 10%折扣
print(f"订单总额: ¥{order.total_amount}")
order.save_to_file("order.json")
# 尝试不合法状态转换
try:
    order.update_status(order.STATUS_COMPLETED)  # 从pending直接到completed不合法
except ValueError as e:
    print(f"状态转换错误: {e}")

封装的实践原则

访问控制级别

class EncapsulationExample:
    """封装级别示例"""
    def __init__(self):
        self.public_attr = "公开属性"      # 公共属性
        self._protected_attr = "受保护属性" # 受保护(约定)
        self.__private_attr = "私有属性"    # 私有(name mangling)
    def public_method(self):
        """公共方法"""
        return "公开方法"
    def _protected_method(self):
        """受保护方法"""
        return "受保护方法"
    def __private_method(self):
        """私有方法"""
        return "私有方法"
    def access_private(self):
        """在类内部访问私有成员"""
        return self.__private_attr + " - " + self.__private_method()

封装的最佳实践

class BestPractices:
    """封装最佳实践示例"""
    def __init__(self):
        # 1. 使用下划线约定
        self._data = []
        # 2. 使用@property提供只读属性
        self._read_only = "不可修改"
        # 3. 在setter中添加验证
        self._age = 0
    # 2. 只读属性
    @property
    def read_only(self):
        return self._read_only
    # 3. 带验证的setter
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, value):
        """验证年龄"""
        if not isinstance(value, int):
            raise TypeError("年龄必须是整数")
        if not 0 <= value <= 150:
            raise ValueError("年龄范围无效")
        self._age = value
    # 4. 返回副本而不是直接返回内部数据
    def get_data(self):
        """返回数据副本"""
        return self._data.copy()
    # 5. 提供明确的操作方法
    def add_item(self, item):
        """添加数据"""
        self._data.append(item)
    def remove_item(self, item):
        """移除数据"""
        if item in self._data:
            self._data.remove(item)
        else:
            raise ValueError(f"数据不存在: {item}")

总结要点

封装的好处:

  1. 数据安全:防止外部直接访问和修改内部数据
  2. 简化接口:只暴露必要的操作接口
  3. 灵活性:修改内部实现不影响外部调用
  4. 可维护性:代码结构清晰,易于维护

封装的原则:

  1. 最小化暴露:只暴露必要的方法和属性
  2. 数据验证:在setter中进行数据验证
  3. 返回副本:对于可变对象,返回副本而非原对象
  4. 提供明确方法:通过方法操作数据,而非直接访问

就是封装的完整案例,从简单到复杂,覆盖了封装的各个层面,选择哪种封装方式,需要根据项目的具体需求来确定。

抱歉,评论功能暂时关闭!