Appearance
面向对象——类、对象、继承、组合
概念讲解
面向对象(OOP) 的核心思想:把数据和操作数据的方法封装在一起。
几个关键概念:
- 类(Class):模板,定义一类事物的共同属性和行为
- 对象(Object):类的实例,具体的一个个体
- 继承(Inheritance):子类复用父类的代码,并可以扩展
- 组合(Composition):一个类包含另一个类的实例作为属性
什么时候用 OOP?
- 当你需要描述的实体有"属性"和"行为"时
- 当多个实体有共同的抽象时,用继承
- 当一个实体由多个部件组成时,用组合
代码示例
组合:订单系统
python
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)继承:银行账户体系
python
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练习题
题目:设计一个图书馆系统,包含以下类:
Book:书(书名、作者、ISBN)Library:图书馆(藏书列表,提供借书/还书/查询方法)Member:会员(姓名、会员ID、可借阅数量限制)
要求:
- 借书时检查会员是否还有借阅额度
- 还书时更新会员的借阅状态
- 可以按书名或作者查询书籍
参考答案
python
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封装借阅状态的判断逻辑 - 异常用于处理"不应该发生"的错误情况