第9章:类(Classes)
一、导读
1.1 本章学习目标
第9章介绍Python的面向对象编程。本章核心目标:
- 掌握类的定义和对象的创建:class关键字
- 理解__init__方法和self参数
- 学会继承和方法重写
- 掌握特殊方法:__str__、__repr__、__eq__等
- 理解类属性和实例属性的区别
1.2 为什么本章如此重要
面向对象编程是组织大型代码的有效方式。Python的OOP语法简洁直观,是学习面向对象思想的理想语言。理解类的设计原则,才能编写出结构清晰的代码。
1.3 核心问题引导
self参数是什么?为什么需要它?
Python的继承和Java/C++有什么不同?
什么是鸭子类型?
类方法和静态方法有什么区别?
二、核心概念详解
9.1 类的基础
python
class Dog:
"""表示狗的类"""
# 类属性
species = "Canis familiaris"
def __init__(self, name, age):
"""初始化属性"""
self.name = name # 实例属性
self.age = age
def sit(self):
"""模拟狗坐下"""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""模拟狗打滚"""
print(f"{self.name} rolled over!")
def __str__(self):
return f"{self.name} ({self.age} years old)"
def __repr__(self):
return f"Dog('{self.name}', {self.age})"
# 创建对象
my_dog = Dog("Buddy", 3)
print(my_dog.name) # Buddy
my_dog.sit() # Buddy is now sitting.
print(my_dog) # Buddy (3 years old)9.2 继承
python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass # 抽象方法
def __str__(self):
return self.name
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# 多态
animals = [Dog("Buddy"), Cat("Whiskers"), Dog("Max")]
for animal in animals:
print(animal.speak())
# super()调用父类方法
class Puppy(Dog):
def __init__(self, name, age, trick_count=0):
super().__init__(name, age)
self.trick_count = trick_count
def learn_trick(self):
self.trick_count += 1
print(f"{self.name} learned a new trick! ({self.trick_count} total)")
puppy = Puppy("Rex", 1)
puppy.sit() # 继承自Dog
puppy.learn_trick() # Puppy自己的方法9.3 特殊方法
python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)
def __abs__(self):
return (self.x**2 + self.y**2) ** 0.5
def __lt__(self, other):
return abs(self) < abs(other)
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2) # (4, 6)
print(abs(p2)) # 5.0
print(p1 < p2) # True9.4 类方法和静态方法
python
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_str):
"""工厂方法"""
year, month, day = map(int, date_str.split('-'))
return cls(year, month, day)
@staticmethod
def is_valid(date_str):
"""验证日期格式"""
try:
parts = date_str.split('-')
return len(parts) == 3 and all(p.isdigit() for p in parts)
except:
return False
def __str__(self):
return f"{self.year}-{self.month:02d}-{self.day:02d}"
# 使用类方法
d = Date.from_string("2024-01-15")
print(d)
# 使用静态方法
print(Date.is_valid("2024-01-15"))9.5 属性装饰器
python
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 below absolute zero!")
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self.celsius = (value - 32) * 5/9
temp = Temperature(25)
print(temp.celsius) # 25
print(temp.fahrenheit) # 77.0
temp.fahrenheit = 100
print(temp.celsius) # 37.78三、实战案例
3.1 银行账户系统
python
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self._balance = balance
self._transactions = []
@property
def balance(self):
return self._balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("Deposit amount must be positive")
self._balance += amount
self._transactions.append(('deposit', amount))
def withdraw(self, amount):
if amount <= 0:
raise ValueError("Withdraw amount must be positive")
if amount > self._balance:
raise ValueError("Insufficient funds")
self._balance -= amount
self._transactions.append(('withdraw', amount))
def get_history(self):
return self._transactions
def __str__(self):
return f"{self.owner}: ${self.balance:.2f}"
class SavingsAccount(BankAccount):
def __init__(self, owner, balance=0, interest_rate=0.01):
super().__init__(owner, balance)
self.interest_rate = interest_rate
def apply_interest(self):
interest = self._balance * self.interest_rate
self.deposit(interest)
# 使用
acc = SavingsAccount("Alice", 1000, 0.05)
acc.deposit(500)
acc.withdraw(200)
acc.apply_interest()
print(acc)
print(acc.get_history())四、本章小结
第9章介绍了Python的面向对象编程:类的定义、__init__和self、继承、特殊方法、类方法/静态方法、属性装饰器。Python的OOP简洁而强大。
五、思考与练习
思考题
Python没有私有成员,如何模拟私有属性?
什么是鸭子类型?和接口有什么关系?
__str__和__repr__有什么区别?
多继承的MRO(方法解析顺序)是什么?
编程练习
实现一个Fraction类,支持分数运算。
实现一个简单的卡牌游戏(使用类)。
使用继承实现一个图形类层次结构。