Skip to content

🎯 高级魔法师实战:面向对象编程高级特性练习

📚 在本练习中,你将巩固Python面向对象编程的高级特性,包括类属性与实例属性、类方法与静态方法、私有属性、继承、多态、魔术方法等。通过实践,让你更深入地理解这些概念并能灵活运用。

🎯 练习目标

  • 掌握类属性与实例属性的区别与使用场景
  • 熟练使用类方法、静态方法和实例方法
  • 理解并应用私有属性和属性访问控制
  • 能够设计和实现类的继承关系
  • 掌握多态的实际应用
  • 了解并使用常用的魔术方法
  • 能够创建和使用抽象基类

🏋️‍♂️ 基础练习题

1. 类属性与实例属性练习

任务: 创建一个 Student 类,包含以下内容:

  • 类属性 total_students 用于跟踪创建的学生总数
  • 类属性 school_name 设置为 "Python University"
  • 实例属性 namestudent_id
  • 一个 display_info 实例方法,打印学生的姓名、学号和学校名称

示例代码框架:

python
class Student:
    # 在这里定义类属性
    
    def __init__(self, name, student_id):
        # 在这里定义实例属性
        # 并更新类属性
    
    def display_info(self):
        # 打印学生信息

测试代码:

python
# 创建学生实例
student1 = Student("张三", "2023001")
student2 = Student("李四", "2023002")

# 显示学生信息
student1.display_info()
student2.display_info()

# 显示总学生数和学校名称
print(f"总学生数: {Student.total_students}")
print(f"学校名称: {Student.school_name}")

2. 类方法与静态方法练习

任务: 扩展上面的 Student 类,添加以下内容:

  • 一个类方法 get_total_students,返回总学生数
  • 一个类方法 change_school_name,修改学校名称
  • 一个静态方法 validate_student_id,验证学生ID是否有效(假设有效格式为6位数字)

测试代码:

python
# 使用类方法
print(f"使用类方法获取总学生数: {Student.get_total_students()}")
Student.change_school_name("Python Institute")
student1.display_info()  # 检查学校名称是否已更改

# 使用静态方法
print(f"2023001是否有效: {Student.validate_student_id('2023001')}")
print(f"ABC123是否有效: {Student.validate_student_id('ABC123')}")

3. 私有属性与属性访问控制练习

任务: 创建一个 BankAccount 类,包含以下内容:

  • 一个私有属性 _balance 用于存储账户余额,初始值为0
  • 一个 deposit 方法,用于存款
  • 一个 withdraw 方法,用于取款(注意:余额不能为负)
  • 使用 @property 装饰器创建一个只读的 balance 属性,用于查看当前余额
  • 添加一个 @balance.setter 装饰器,允许通过属性设置余额,但仍然进行验证

示例代码框架:

python
class BankAccount:
    def __init__(self):
        self._balance = 0
    
    def deposit(self, amount):
        # 实现存款功能
    
    def withdraw(self, amount):
        # 实现取款功能,确保余额不为负
    
    @property
    def balance(self):
        # 返回当前余额
    
    @balance.setter
    def balance(self, amount):
        # 设置余额,确保金额有效

测试代码:

python
account = BankAccount()
account.deposit(1000)
print(f"当前余额: {account.balance}")
account.withdraw(500)
print(f"取款后余额: {account.balance}")
# account.withdraw(1000)  # 这应该引发错误或提示
account.balance = 2000
print(f"设置后余额: {account.balance}")
# account.balance = -100  # 这应该引发错误或提示

4. 继承练习

任务: 创建一个继承层次结构,表示不同类型的银行账户:

  • 创建一个基础类 Account,包含账户持有者姓名和余额属性,以及存款和取款方法
  • 创建两个子类:SavingsAccountCheckingAccount
  • SavingsAccount 应该有一个 interest_rate 属性和一个 add_interest 方法,用于计算和添加利息
  • CheckingAccount 应该有一个 transaction_fee 属性,并且取款时会收取费用

测试代码:

python
savings = SavingsAccount("王五", 1000, 0.05)  # 5% 利率
checking = CheckingAccount("赵六", 1000, 2)  # 2元交易费

savings.deposit(500)
savings.add_interest()
print(f"储蓄账户余额: {savings.balance}")

checking.withdraw(100)
print(f"支票账户余额: {checking.balance}")

5. 魔术方法练习

任务: 创建一个 Book 类,实现以下魔术方法:

  • __init__: 初始化书名、作者和价格
  • __str__: 返回书籍的可读字符串表示
  • __repr__: 返回书籍的"官方"字符串表示
  • __eq__: 比较两本书是否相同(基于书名和作者)
  • __lt__: 基于价格比较两本书
  • __add__: 实现两本书的"组合"(返回包含两本书的列表)

测试代码:

python
book1 = Book("Python编程", "张三", 99.0)
book2 = Book("Python高级编程", "李四", 129.0)
book3 = Book("Python编程", "张三", 99.0)

print(book1)  # 测试 __str__
print(repr(book1))  # 测试 __repr__
print(book1 == book2)  # 测试 __eq__
print(book1 == book3)  # 测试 __eq__
print(book1 < book2)  # 测试 __lt__
combined = book1 + book2  # 测试 __add__
print(f"组合结果: {combined}")

🚀 挑战题

1. 图形类层次结构

任务: 创建一个图形类层次结构,包含抽象基类和具体实现类:

  1. 创建一个抽象基类 Shape,定义以下抽象方法:

    • area(): 计算图形面积
    • perimeter(): 计算图形周长
    • display(): 显示图形信息
  2. 实现以下具体子类:

    • Rectangle: 矩形,需要 width 和 height 参数
    • Circle: 圆形,需要 radius 参数
    • Triangle: 三角形,需要 a, b, c 三个边长参数
    • Polygon: 多边形,需要一个边长列表参数
  3. 创建一个 ShapeCollection 类,用于管理多个图形对象:

    • 实现 add_shape 方法添加图形
    • 实现 total_area 方法计算所有图形的总面积
    • 实现 total_perimeter 方法计算所有图形的总周长
    • 实现 display_all 方法显示所有图形的信息
    • 实现 __len__ 魔术方法返回图形数量
    • 实现 __getitem__ 魔术方法支持通过索引访问图形

测试代码:

python
# 创建图形集合
shapes = ShapeCollection()

# 添加各种图形
shapes.add_shape(Rectangle(5, 3))
shapes.add_shape(Circle(4))
shapes.add_shape(Triangle(3, 4, 5))
shapes.add_shape(Polygon([3, 4, 5, 6]))

# 显示所有图形信息
shapes.display_all()

# 计算总面积和总周长
print(f"总面积: {shapes.total_area():.2f}")
print(f"总周长: {shapes.total_perimeter():.2f}")
print(f"图形数量: {len(shapes)}")

# 访问特定图形
first_shape = shapes[0]
print(f"第一个图形: {first_shape}")
print(f"第一个图形的面积: {first_shape.area():.2f}")

2. 电子商务系统

任务: 创建一个简化的电子商务系统,包含以下类:

  1. Product 类:表示商品

    • 属性:product_id, name, price, stock_quantity
    • 方法:reduce_stock(quantity) 减少库存
    • 魔术方法:__str____repr__
  2. Customer 类:表示顾客

    • 属性:customer_id, name, email, address
    • 方法:update_address(new_address) 更新地址
  3. Order 类:表示订单

    • 属性:order_id, customer, products (产品及其数量的字典), status, order_date
    • 方法:add_product(product, quantity) 添加产品
    • 方法:remove_product(product_id) 移除产品
    • 方法:calculate_total() 计算订单总金额
    • 方法:update_status(new_status) 更新订单状态
    • 魔术方法:__str__
  4. ShoppingCart 类:表示购物车

    • 属性:products (产品及其数量的字典)
    • 方法:add_item(product, quantity) 添加商品
    • 方法:remove_item(product_id) 移除商品
    • 方法:update_quantity(product_id, quantity) 更新商品数量
    • 方法:calculate_total() 计算购物车总金额
    • 方法:checkout(customer) 结账并创建订单
    • 魔术方法:__len____iter__ (支持遍历购物车中的商品)

测试代码:

python
# 创建产品
product1 = Product(1, "Python编程书籍", 99.0, 100)
product2 = Product(2, "编程鼠标垫", 29.0, 200)
product3 = Product(3, "机械键盘", 499.0, 50)

# 创建顾客
customer = Customer(1, "张三", "zhangsan@example.com", "北京市海淀区")

# 创建购物车并添加商品
cart = ShoppingCart()
cart.add_item(product1, 2)
cart.add_item(product2, 3)
cart.add_item(product3, 1)

# 显示购物车信息
print(f"购物车商品数量: {len(cart)}")
print(f"购物车总金额: ¥{cart.calculate_total():.2f}")

# 遍历购物车商品
print("购物车中的商品:")
for item, quantity in cart:
    print(f"  {item.name}: {quantity}件")

# 更新商品数量
cart.update_quantity(2, 1)
print(f"更新后购物车总金额: ¥{cart.calculate_total():.2f}")

# 结账并创建订单
order = cart.checkout(customer)
print(f"订单创建成功: {order}")
print(f"订单总金额: ¥{order.calculate_total():.2f}")

# 检查产品库存
print(f"Python编程书籍剩余库存: {product1.stock_quantity}")

💡 实践应用提示

  1. 设计类的层次结构时,先确定抽象基类,定义清晰的接口,然后再实现具体子类。

  2. 使用私有属性来保护内部状态,只提供必要的公共接口。

  3. 合理使用属性装饰器,可以在不改变接口的情况下,增加属性访问的控制逻辑。

  4. 遵循"组合优先于继承"原则,当不需要继承的全部功能时,考虑使用组合关系。

  5. 利用多态特性,可以编写更通用的代码,提高代码的可扩展性。

  6. 使用魔术方法可以使你的类与Python的内置功能更好地集成。

  7. 编写单元测试来验证你的类的行为是否符合预期。

📝 参考实现(部分)

以下是部分练习题的参考实现,供你完成练习后对照检查:

1. 类属性与实例属性练习参考实现

python
class Student:
    # 类属性
    total_students = 0
    school_name = "Python University"
    
    def __init__(self, name, student_id):
        # 实例属性
        self.name = name
        self.student_id = student_id
        # 更新类属性
        Student.total_students += 1
    
    def display_info(self):
        print(f"姓名: {self.name}, 学号: {self.student_id}, 学校: {self.school_name}")

2. 类方法与静态方法练习参考实现

python
class Student:
    # 类属性
    total_students = 0
    school_name = "Python University"
    
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
        Student.total_students += 1
    
    def display_info(self):
        print(f"姓名: {self.name}, 学号: {self.student_id}, 学校: {self.school_name}")
    
    @classmethod
    def get_total_students(cls):
        return cls.total_students
    
    @classmethod
    def change_school_name(cls, new_name):
        cls.school_name = new_name
    
    @staticmethod
    def validate_student_id(student_id):
        return len(student_id) == 6 and student_id.isdigit()

3. 私有属性与属性访问控制练习参考实现

python
class BankAccount:
    def __init__(self):
        self._balance = 0
    
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
            return f"存款成功,金额: ¥{amount}"
        else:
            return "存款金额必须为正数"
    
    def withdraw(self, amount):
        if amount <= 0:
            return "取款金额必须为正数"
        if amount > self._balance:
            return "余额不足"
        self._balance -= amount
        return f"取款成功,金额: ¥{amount}"
    
    @property
    def balance(self):
        return self._balance
    
    @balance.setter
    def balance(self, amount):
        if amount < 0:
            raise ValueError("余额不能为负数")
        self._balance = amount

完成这些练习后,你将对Python面向对象编程的高级特性有更深入的理解和应用能力。记得在实际项目中灵活运用这些知识,编写更加优雅、可维护的代码!💪 完成这些练习后,你将对Python面向对象编程的高级特性有更深入的理解和应用能力。记得在实际项目中灵活运用这些知识,编写更加优雅、可维护的代码!💪

© 2025 技术博客. All rights reserved by 老周有AI