初面网初面网

面向对象——类、对象、继承、组合

概念讲解

面向对象(OOP) 的核心思想:把数据和操作数据的方法封装在一起。

几个关键概念:

  • 类(Class):模板,定义一类事物的共同属性和行为
  • 对象(Object):类的实例,具体的一个个体
  • 继承(Inheritance):子类复用父类的代码,并可以扩展
  • 组合(Composition):一个类包含另一个类的实例作为属性

什么时候用 OOP?

  • 当你需要描述的实体有"属性"和"行为"时
  • 当多个实体有共同的抽象时,用继承
  • 当一个实体由多个部件组成时,用组合

代码示例

组合:订单系统

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price
    
    def __repr__(self):
        return f"{self.name}{self.price})"

class OrderItem:
    def __init__(self, product, quantity):
        self.product = product
        self.quantity = quantity
    
    @property
    def subtotal(self):
        return self.product.price * self.quantity

class Order:
    def __init__(self, customer):
        self.customer = customer
        self.items = []
        self.status = "pending"
    
    def add_item(self, product, quantity):
        self.items.append(OrderItem(product, quantity))
    
    @property
    def total(self):
        return sum(item.subtotal for item in self.items)
    
    def __repr__(self):
        item_lines = "\n".join(f"  - {i.product.name} x{i.quantity} = ¥{i.subtotal}" 
                               for i in self.items)
        return f"订单(客户:{self.customer}\n{item_lines}\n总计:¥{self.total}"

# 使用
order = Order("张三")
order.add_item(Product("Python入门", 49), 2)
order.add_item(Product("数据结构与算法", 79), 1)
print(order)

继承:银行账户体系

class Account:
    def __init__(self, account_id, owner):
        self.account_id = account_id
        self.owner = owner
        self.balance = 0.0
    
    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("存款金额必须为正")
        self.balance += amount
        return self.balance
    
    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("余额不足")
        self.balance -= amount
        return self.balance

class SavingsAccount(Account):
    """带利息的储蓄账户"""
    def __init__(self, account_id, owner, interest_rate=0.03):
        super().__init__(account_id, owner)
        self.interest_rate = interest_rate
    
    def apply_interest(self):
        interest = self.balance * self.interest_rate
        self.balance += interest
        return interest

# 测试
acc = SavingsAccount("SA001", "李四", 0.05)
acc.deposit(10000)
acc.apply_interest()
print(f"余额:¥{acc.balance:.2f}")  # 余额:¥10500.00

练习题

题目:设计一个图书馆系统,包含以下类:

  1. Book:书(书名、作者、ISBN)
  2. Library:图书馆(藏书列表,提供借书/还书/查询方法)
  3. Member:会员(姓名、会员ID、可借阅数量限制)

要求:

  • 借书时检查会员是否还有借阅额度
  • 还书时更新会员的借阅状态
  • 可以按书名或作者查询书籍
参考答案
class Book:
    def __init__(self, title, author, isbn):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.borrowed = False
    
    def __repr__(self):
        status = "已借出" if self.borrowed else "在架"
        return f'"{self.title}" by {self.author} [{status}]'

class Member:
    def __init__(self, name, member_id, max_borrow=3):
        self.name = name
        self.member_id = member_id
        self.max_borrow = max_borrow
        self.borrowed_books = []
    
    @property
    def can_borrow(self):
        return len(self.borrowed_books) < self.max_borrow
    
    def borrow_book(self, book):
        if not self.can_borrow:
            raise ValueError(f"已达借阅上限({self.max_borrow}本)")
        if book.borrowed:
            raise ValueError(f"《{book.title}》已被借出")
        book.borrowed = True
        self.borrowed_books.append(book)
    
    def return_book(self, book):
        if book in self.borrowed_books:
            book.borrowed = False
            self.borrowed_books.remove(book)
        else:
            raise ValueError(f"该书不在借阅记录中")

class Library:
    def __init__(self):
        self.books = []
    
    def add_book(self, book):
        self.books.append(book)
    
    def search(self, keyword):
        return [b for b in self.books 
                if keyword.lower() in b.title.lower() 
                or keyword.lower() in b.author.lower()]
    
    def borrow(self, member, book):
        member.borrow_book(book)
    
    def return_book(self, member, book):
        member.return_book(book)

# 测试
lib = Library()
lib.add_book(Book("Python编程", "张三", "ISBN001"))
lib.add_book(Book("数据结构", "李四", "ISBN002"))
lib.add_book(Book("Python算法", "王五", "ISBN003"))

member = Member("赵六", "M001")
lib.borrow(member, lib.books[0])
print(lib.books[0])  # "Python编程" by 张三 [已借出]
print(member.borrowed_books)  # [书对象]
print(lib.search("Python"))   # 两本Python书

关键思维:

  • 组合优于继承:Library包含Book和Member,而非让它们继承
  • @property 封装借阅状态的判断逻辑
  • 异常用于处理"不应该发生"的错误情况

更新于 2026/6/7