Python 面向对象编程
目录
面向对象基础
什么是面向对象?
面向对象编程(OOP)是一种编程范式,它将数据和操作数据的方法组织成"对象"。
核心概念:
- 类(Class):对象的蓝图或模板
- 对象(Object):类的实例
- 属性(Attribute):对象的数据
- 方法(Method):对象的行为
# 面向过程 vs 面向对象
# ❌ 面向过程
def create_dog(name, age):
return {"name": name, "age": age}
def dog_bark(dog):
print(f"{dog['name']} says: Woof!")
my_dog = create_dog("Buddy", 3)
dog_bark(my_dog)
# ✅ 面向对象
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says: Woof!")
my_dog = Dog("Buddy", 3)
my_dog.bark()
面向对象的四大特性
- 封装:隐藏内部实现细节
- 继承:代码复用和扩展
- 多态:同一接口,不同实现
- 抽象:提取共同特征
类和对象
定义类
# 基本类定义
class Person:
"""人类"""
pass
# 创建对象
person1 = Person()
person2 = Person()
print(type(person1)) # <class '__main__.Person'>
print(person1 is person2) # False(不同的对象)
添加属性和方法
class Person:
"""人类"""
def greet(self):
"""打招呼"""
print("Hello!")
# 使用
person = Person()
person.greet() # Hello!
构造函数
__init__ 方法
class Person:
def __init__(self, name, age):
"""构造函数,在创建对象时自动调用"""
self.name = name # 实例属性
self.age = age
print(f"创建了 {self.name}")
# 创建对象时传入参数
person = Person("张三", 25)
print(person.name) # 张三
print(person.age) # 25
默认参数
class Person:
def __init__(self, name, age=0, city="未知"):
self.name = name
self.age = age
self.city = city
person1 = Person("张三")
person2 = Person("李四", 25)
person3 = Person("王五", 30, "北京")
print(person1.city) # 未知
print(person2.age) # 25
print(person3.city) # 北京
实例属性和方法
实例属性
class Student:
def __init__(self, name, student_id):
self.name = name # 实例属性
self.student_id = student_id
self.grades = [] # 可变属性
# 每个对象有独立的属性
student1 = Student("张三", "001")
student2 = Student("李四", "002")
student1.grades.append(90)
student2.grades.append(85)
print(student1.grades) # [90]
print(student2.grades) # [85]
实例方法
class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
self.grades = []
def add_grade(self, grade):
"""添加成绩"""
if 0 <= grade <= 100:
self.grades.append(grade)
print(f"添加成绩: {grade}")
else:
print("成绩必须在0-100之间")
def get_average(self):
"""计算平均分"""
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
def display_info(self):
"""显示学生信息"""
avg = self.get_average()
print(f"姓名: {self.name}")
print(f"学号: {self.student_id}")
print(f"成绩: {self.grades}")
print(f"平均分: {avg:.2f}")
# 使用
student = Student("张三", "001")
student.add_grade(90)
student.add_grade(85)
student.add_grade(92)
student.display_info()
self 参数
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
# self 指向当前对象实例
print(f"{self.name} says: Woof!")
def introduce(self):
# 可以调用其他方法
self.bark()
print(f"I am {self.name}")
dog = Dog("Buddy")
dog.introduce()
# Buddy says: Woof!
# I am Buddy
类属性和类方法
类属性
class Employee:
# 类属性(所有实例共享)
company = "ABC公司"
employee_count = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
# 每创建一个员工,计数+1
Employee.employee_count += 1
emp1 = Employee("张三", 8000)
emp2 = Employee("李四", 9000)
# 访问类属性
print(Employee.company) # ABC公司
print(Employee.employee_count) # 2
print(emp1.company) # ABC公司(也可以通过实例访问)
print(emp2.employee_count) # 2
类方法
class Employee:
company = "ABC公司"
def __init__(self, name, salary):
self.name = name
self.salary = salary
@classmethod
def change_company(cls, new_company):
"""类方法:修改公司名称"""
cls.company = new_company
print(f"公司更名为: {new_company}")
@classmethod
def from_string(cls, emp_str):
"""类方法:从字符串创建对象"""
name, salary = emp_str.split("-")
return cls(name, int(salary))
# 使用类方法
Employee.change_company("XYZ公司")
# 工厂方法
emp = Employee.from_string("王五-10000")
print(emp.name) # 王五
print(emp.salary) # 10000
静态方法
class MathUtils:
@staticmethod
def add(a, b):
"""静态方法:不需要访问类或实例"""
return a + b
@staticmethod
def is_even(number):
return number % 2 == 0
@staticmethod
def validate_email(email):
"""验证邮箱格式"""
return "@" in email and "." in email
# 使用静态方法(不需要创建实例)
print(MathUtils.add(5, 3)) # 8
print(MathUtils.is_even(10)) # True
print(MathUtils.validate_email("test@example.com")) # True
三种方法对比
class MyClass:
class_var = "类变量"
def __init__(self, value):
self.instance_var = value
def instance_method(self):
"""实例方法:可以访问实例和类"""
print(f"实例变量: {self.instance_var}")
print(f"类变量: {MyClass.class_var}")
@classmethod
def class_method(cls):
"""类方法:只能访问类"""
print(f"类变量: {cls.class_var}")
# print(self.instance_var) # ❌ 错误
@staticmethod
def static_method():
"""静态方法:不能访问实例或类"""
print("静态方法")
# print(self.instance_var) # ❌ 错误
# print(MyClass.class_var) # 可以但不推荐
obj = MyClass("实例值")
obj.instance_method()
MyClass.class_method()
MyClass.static_method()
封装
访问控制
Python 没有严格的访问控制,但有以下约定:
public:公开(默认)_protected:受保护(约定,不强制)__private:私有(名称修饰)
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner # 公开
self._balance = balance # 受保护(约定不要直接访问)
self.__pin = "1234" # 私有(名称修饰)
def deposit(self, amount):
if amount > 0:
self._balance += amount
print(f"存入: {amount}, 余额: {self._balance}")
def withdraw(self, amount):
if 0 < amount <= self._balance:
self._balance -= amount
print(f"取出: {amount}, 余额: {self._balance}")
else:
print("余额不足")
def get_balance(self):
"""公开方法访问受保护的属性"""
return self._balance
account = BankAccount("张三", 1000)
account.deposit(500)
account.withdraw(200)
print(account.get_balance()) # 1300
# ❌ 不推荐直接访问
# print(account._balance)
# ❌ 无法直接访问私有属性
# print(account.__pin) # AttributeError
# 实际上可以通过名称修饰访问(但不应该这样做)
print(account._BankAccount__pin) # 1234(不推荐)
Getter 和 Setter
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius
# Getter
def get_celsius(self):
return self._celsius
# Setter
def set_celsius(self, value):
if value < -273.15:
raise ValueError("温度不能低于绝对零度")
self._celsius = value
def get_fahrenheit(self):
return self._celsius * 9/5 + 32
temp = Temperature(25)
print(temp.get_celsius()) # 25
print(temp.get_fahrenheit()) # 77.0
temp.set_celsius(30)
print(temp.get_celsius()) # 30
继承
基本继承
# 父类(基类)
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} makes a sound")
def describe(self):
print(f"{self.name}, {self.age}岁")
# 子类(派生类)
class Dog(Animal):
def speak(self):
print(f"{self.name} says: Woof!")
class Cat(Animal):
def speak(self):
print(f"{self.name} says: Meow!")
# 使用
dog = Dog("Buddy", 3)
cat = Cat("Kitty", 2)
dog.describe() # Buddy, 3岁
dog.speak() # Buddy says: Woof!
cat.describe() # Kitty, 2岁
cat.speak() # Kitty says: Meow!
super() 函数
class Bird(Animal):
def __init__(self, name, age, can_fly=True):
# 调用父类的构造函数
super().__init__(name, age)
self.can_fly = can_fly
def describe(self):
# 调用父类的方法
super().describe()
fly_status = "会飞" if self.can_fly else "不会飞"
print(f"飞行能力: {fly_status}")
bird = Bird("鹦鹉", 5, True)
bird.describe()
# 鹦鹉, 5岁
# 飞行能力: 会飞
多层继承
class GrandParent:
def __init__(self):
self.family_name = "张"
class Parent(GrandParent):
def __init__(self):
super().__init__()
self.generation = "父母辈"
class Child(Parent):
def __init__(self, name):
super().__init__()
self.name = name
def introduce(self):
print(f"我叫{self.name},姓{self.family_name},是{self.generation}")
child = Child("小明")
child.introduce() # 我叫小明,姓张,是父母辈
多重继承
class Flyable:
def fly(self):
print("我在飞")
class Swimmable:
def swim(self):
print("我在游泳")
class Duck(Flyable, Swimmable):
def __init__(self, name):
self.name = name
def introduce(self):
print(f"我是{self.name}")
duck = Duck("唐老鸭")
duck.introduce() # 我是唐老鸭
duck.fly() # 我在飞
duck.swim() # 我在游泳
MRO(方法解析顺序)
class A:
def method(self):
print("A.method")
class B(A):
def method(self):
print("B.method")
class C(A):
def method(self):
print("C.method")
class D(B, C):
pass
d = D()
d.method() # B.method
# 查看MRO
print(D.mro())
# [<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>]
isinstance 和 issubclass
class Animal:
pass
class Dog(Animal):
pass
class Cat(Animal):
pass
dog = Dog()
# 检查实例类型
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(dog, Cat)) # False
# 检查类的继承关系
print(issubclass(Dog, Animal)) # True
print(issubclass(Cat, Animal)) # True
print(issubclass(Dog, Cat)) # False
多态
方法重写
class Shape:
def area(self):
raise NotImplementedError("子类必须实现此方法")
def describe(self):
print(f"面积: {self.area()}")
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
# 多态:同样的接口,不同的行为
shapes = [Rectangle(5, 10), Circle(7)]
for shape in shapes:
shape.describe()
# 面积: 50
# 面积: 153.938...
鸭子类型
# Python 的鸭子类型:"如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子"
class Duck:
def quack(self):
print("Quack!")
class Person:
def quack(self):
print("我在模仿鸭子叫")
def make_it_quack(thing):
# 不关心类型,只关心是否有 quack 方法
thing.quack()
make_it_quack(Duck()) # Quack!
make_it_quack(Person()) # 我在模仿鸭子叫
魔术方法
魔术方法(特殊方法)以双下划线开头和结尾,用于自定义类的行为。
字符串表示
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""用户友好的字符串表示"""
return f"{self.name}({self.age}岁)"
def __repr__(self):
"""开发者友好的字符串表示"""
return f"Person('{self.name}', {self.age})"
person = Person("张三", 25)
print(str(person)) # 张三(25岁)
print(repr(person)) # Person('张三', 25)
比较运算符
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __eq__(self, other):
"""=="""
if isinstance(other, Student):
return self.score == other.score
return NotImplemented
def __lt__(self, other):
"""<"""
if isinstance(other, Student):
return self.score < other.score
return NotImplemented
def __le__(self, other):
"""<="""
if isinstance(other, Student):
return self.score <= other.score
return NotImplemented
def __gt__(self, other):
""">"""
if isinstance(other, Student):
return self.score > other.score
return NotImplemented
def __ge__(self, other):
""">="""
if isinstance(other, Student):
return self.score >= other.score
return NotImplemented
s1 = Student("张三", 90)
s2 = Student("李四", 85)
print(s1 > s2) # True
print(s1 == s2) # False
print(s1 >= s2) # True
算术运算符
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
"""+"""
if isinstance(other, Vector):
return Vector(self.x + other.x, self.y + other.y)
return NotImplemented
def __sub__(self, other):
"""-"""
if isinstance(other, Vector):
return Vector(self.x - other.x, self.y - other.y)
return NotImplemented
def __mul__(self, scalar):
"""*"""
if isinstance(scalar, (int, float)):
return Vector(self.x * scalar, self.y * scalar)
return NotImplemented
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 - v2) # Vector(-2, -2)
print(v1 * 3) # Vector(3, 6)
容器相关方法
class MyList:
def __init__(self, items=None):
self.items = items or []
def __len__(self):
"""len()"""
return len(self.items)
def __getitem__(self, index):
"""索引访问"""
return self.items[index]
def __setitem__(self, index, value):
"""索引赋值"""
self.items[index] = value
def __delitem__(self, index):
"""删除元素"""
del self.items[index]
def __contains__(self, item):
"""in 操作符"""
return item in self.items
def __iter__(self):
"""迭代"""
return iter(self.items)
def __str__(self):
return str(self.items)
my_list = MyList([1, 2, 3, 4, 5])
print(len(my_list)) # 5
print(my_list[0]) # 1
print(3 in my_list) # True
for item in my_list:
print(item, end=" ") # 1 2 3 4 5
常用魔术方法总结
class Example:
# 初始化和销毁
def __init__(self): # 构造
pass
def __del__(self): # 析构
pass
# 字符串表示
def __str__(self): # str()
pass
def __repr__(self): # repr()
pass
# 比较
def __eq__(self, other): # ==
pass
def __lt__(self, other): # <
pass
# 算术
def __add__(self, other): # +
pass
def __sub__(self, other): # -
pass
# 容器
def __len__(self): # len()
pass
def __getitem__(self, key): # obj[key]
pass
def __setitem__(self, key, value): # obj[key] = value
pass
def __contains__(self, item): # in
pass
def __iter__(self): # iter()
pass
# 调用
def __call__(self, *args): # obj()
pass
# 上下文管理器
def __enter__(self): # with语句进入
pass
def __exit__(self, *args): # with语句退出
pass
属性装饰器
@property
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""getter"""
return self._radius
@radius.setter
def radius(self, value):
"""setter"""
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@property
def area(self):
"""只读属性"""
import math
return math.pi * self._radius ** 2
circle = Circle(5)
print(circle.radius) # 5(调用 getter)
print(circle.area) # 78.54...(只读)
circle.radius = 10 # 调用 setter
print(circle.radius) # 10
# circle.area = 100 # ❌ AttributeError: 只读
计算属性
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
@property
def perimeter(self):
return 2 * (self.width + self.height)
@property
def is_square(self):
return self.width == self.height
rect = Rectangle(5, 10)
print(rect.area) # 50
print(rect.perimeter) # 30
print(rect.is_square) # False
组合与聚合
组合(强关系)
class Engine:
def __init__(self, horsepower):
self.horsepower = horsepower
def start(self):
print(f"引擎启动 ({self.horsepower}马力)")
class Car:
def __init__(self, brand, engine):
self.brand = brand
self.engine = engine # 组合:Car 拥有 Engine
def start(self):
print(f"{self.brand} 汽车启动")
self.engine.start()
# Engine 是 Car 的一部分,生命周期绑定
engine = Engine(200)
car = Car("丰田", engine)
car.start()
# 丰田 汽车启动
# 引擎启动 (200马力)
聚合(弱关系)
class Teacher:
def __init__(self, name):
self.name = name
class Department:
def __init__(self, name):
self.name = name
self.teachers = [] # 聚合:Department 包含 Teachers
def add_teacher(self, teacher):
self.teachers.append(teacher)
def list_teachers(self):
print(f"{self.name} 的教师:")
for teacher in self.teachers:
print(f" - {teacher.name}")
# Teacher 可以独立于 Department 存在
teacher1 = Teacher("张老师")
teacher2 = Teacher("李老师")
dept = Department("计算机系")
dept.add_teacher(teacher1)
dept.add_teacher(teacher2)
dept.list_teachers()
抽象基类
ABC 模块
from abc import ABC, abstractmethod
class Shape(ABC):
"""抽象基类"""
@abstractmethod
def area(self):
"""计算面积(必须由子类实现)"""
pass
@abstractmethod
def perimeter(self):
"""计算周长(必须由子类实现)"""
pass
def describe(self):
"""具体方法(可选实现)"""
print(f"面积: {self.area()}, 周长: {self.perimeter()}")
# ❌ 不能实例化抽象类
# shape = Shape() # TypeError
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def perimeter(self):
import math
return 2 * math.pi * self.radius
# ✅ 可以实例化具体子类
rect = Rectangle(5, 10)
rect.describe()
circle = Circle(7)
circle.describe()
综合实战
实战1: 银行账户系统
from abc import ABC, abstractmethod
from datetime import datetime
class Transaction:
"""交易记录"""
def __init__(self, transaction_type, amount, description=""):
self.type = transaction_type # "deposit" 或 "withdrawal"
self.amount = amount
self.description = description
self.timestamp = datetime.now()
def __str__(self):
type_cn = "存款" if self.type == "deposit" else "取款"
return f"[{self.timestamp}] {type_cn}: ¥{self.amount:.2f} {self.description}"
class BankAccount(ABC):
"""银行账户抽象基类"""
def __init__(self, owner, account_number, initial_balance=0):
self.owner = owner
self.account_number = account_number
self._balance = initial_balance
self.transactions = []
if initial_balance > 0:
self.transactions.append(
Transaction("deposit", initial_balance, "初始存款")
)
@property
def balance(self):
return self._balance
def deposit(self, amount):
"""存款"""
if amount <= 0:
raise ValueError("存款金额必须大于0")
self._balance += amount
transaction = Transaction("deposit", amount)
self.transactions.append(transaction)
print(f"✓ 存款成功: ¥{amount:.2f}, 余额: ¥{self._balance:.2f}")
def withdraw(self, amount):
"""取款"""
if amount <= 0:
raise ValueError("取款金额必须大于0")
if amount > self._balance:
raise ValueError("余额不足")
self._balance -= amount
transaction = Transaction("withdrawal", amount)
self.transactions.append(transaction)
print(f"✓ 取款成功: ¥{amount:.2f}, 余额: ¥{self._balance:.2f}")
def get_statement(self):
"""获取账单"""
print(f"\n{'='*50}")
print(f"账户持有人: {self.owner}")
print(f"账号: {self.account_number}")
print(f"当前余额: ¥{self._balance:.2f}")
print(f"{'='*50}")
print("交易记录:")
for transaction in self.transactions[-10:]: # 最近10条
print(f" {transaction}")
print(f"{'='*50}\n")
@abstractmethod
def calculate_interest(self):
"""计算利息(由子类实现)"""
pass
class SavingsAccount(BankAccount):
"""储蓄账户"""
def __init__(self, owner, account_number, interest_rate=0.03, initial_balance=0):
super().__init__(owner, account_number, initial_balance)
self.interest_rate = interest_rate
def calculate_interest(self):
"""计算年利息"""
interest = self._balance * self.interest_rate
print(f"年利息率: {self.interest_rate*100}%")
print(f"年利息: ¥{interest:.2f}")
return interest
class CheckingAccount(BankAccount):
"""支票账户"""
def __init__(self, owner, account_number, overdraft_limit=0, initial_balance=0):
super().__init__(owner, account_number, initial_balance)
self.overdraft_limit = overdraft_limit
def withdraw(self, amount):
"""支持透支"""
if amount <= 0:
raise ValueError("取款金额必须大于0")
if amount > self._balance + self.overdraft_limit:
raise ValueError("超过透支额度")
self._balance -= amount
transaction = Transaction("withdrawal", amount)
self.transactions.append(transaction)
print(f"✓ 取款成功: ¥{amount:.2f}, 余额: ¥{self._balance:.2f}")
def calculate_interest(self):
"""支票账户通常无利息"""
print("支票账户无利息")
return 0
# 使用示例
savings = SavingsAccount("张三", "SAV001", interest_rate=0.03, initial_balance=10000)
savings.deposit(5000)
savings.withdraw(2000)
savings.calculate_interest()
savings.get_statement()
checking = CheckingAccount("李四", "CHK001", overdraft_limit=5000, initial_balance=1000)
checking.withdraw(3000) # 透支
checking.get_statement()
实战2: RPG 游戏角色系统
from abc import ABC, abstractmethod
import random
class Item:
"""物品"""
def __init__(self, name, value):
self.name = name
self.value = value
def __str__(self):
return f"{self.name} (价值: {self.value})"
class Weapon(Item):
"""武器"""
def __init__(self, name, value, damage):
super().__init__(name, value)
self.damage = damage
def __str__(self):
return f"⚔️ {self.name} (攻击力: {self.damage}, 价值: {self.value})"
class Armor(Item):
"""护甲"""
def __init__(self, name, value, defense):
super().__init__(name, value)
self.defense = defense
def __str__(self):
return f"🛡️ {self.name} (防御力: {self.defense}, 价值: {self.value})"
class Character(ABC):
"""角色抽象基类"""
def __init__(self, name, level=1):
self.name = name
self.level = level
self.max_hp = 100 + (level - 1) * 20
self.hp = self.max_hp
self.base_attack = 10 + (level - 1) * 5
self.base_defense = 5 + (level - 1) * 3
self.experience = 0
self.inventory = []
self.equipped_weapon = None
self.equipped_armor = None
@property
def attack(self):
"""总攻击力"""
weapon_damage = self.equipped_weapon.damage if self.equipped_weapon else 0
return self.base_attack + weapon_damage
@property
def defense(self):
"""总防御力"""
armor_defense = self.equipped_armor.defense if self.equipped_armor else 0
return self.base_defense + armor_defense
def take_damage(self, damage):
"""受到伤害"""
actual_damage = max(1, damage - self.defense)
self.hp -= actual_damage
print(f"{self.name} 受到 {actual_damage} 点伤害")
if self.hp <= 0:
self.hp = 0
print(f"{self.name} 被击败了!")
return True
return False
def heal(self, amount):
"""治疗"""
old_hp = self.hp
self.hp = min(self.max_hp, self.hp + amount)
healed = self.hp - old_hp
print(f"{self.name} 恢复了 {healed} 点生命值")
def add_item(self, item):
"""添加物品"""
self.inventory.append(item)
print(f"{self.name} 获得了 {item}")
def equip_weapon(self, weapon):
"""装备武器"""
if weapon in self.inventory:
self.equipped_weapon = weapon
print(f"{self.name} 装备了 {weapon.name}")
else:
print(f"{self.name} 没有 {weapon.name}")
def equip_armor(self, armor):
"""装备护甲"""
if armor in self.inventory:
self.equipped_armor = armor
print(f"{self.name} 装备了 {armor.name}")
else:
print(f"{self.name} 没有 {armor.name}")
def gain_experience(self, exp):
"""获得经验"""
self.experience += exp
print(f"{self.name} 获得 {exp} 点经验")
# 简单升级逻辑
exp_needed = self.level * 100
if self.experience >= exp_needed:
self.level_up()
def level_up(self):
"""升级"""
self.level += 1
self.max_hp += 20
self.hp = self.max_hp
self.base_attack += 5
self.base_defense += 3
print(f"🎉 {self.name} 升级到 {self.level} 级!")
def show_status(self):
"""显示状态"""
print(f"\n{'='*40}")
print(f"👤 {self.name} (Lv.{self.level})")
print(f"❤️ HP: {self.hp}/{self.max_hp}")
print(f"⚔️ 攻击: {self.attack}")
print(f"🛡️ 防御: {self.defense}")
print(f"⭐ 经验: {self.experience}")
if self.equipped_weapon:
print(f"武器: {self.equipped_weapon.name}")
if self.equipped_armor:
print(f"护甲: {self.equipped_armor.name}")
if self.inventory:
print(f"背包: {[str(item) for item in self.inventory]}")
print(f"{'='*40}\n")
@abstractmethod
def special_ability(self):
"""特殊技能(由子类实现)"""
pass
class Warrior(Character):
"""战士"""
def special_ability(self):
"""狂暴:大幅提升攻击力"""
print(f"💥 {self.name} 使用狂暴!")
old_attack = self.base_attack
self.base_attack *= 2
print(f"攻击力从 {old_attack} 提升到 {self.base_attack}")
return "狂暴"
class Mage(Character):
"""法师"""
def __init__(self, name, level=1):
super().__init__(name, level)
self.mana = 50 + (level - 1) * 10
self.max_mana = self.mana
def special_ability(self):
"""火球术:魔法攻击"""
if self.mana >= 20:
self.mana -= 20
damage = self.attack * 1.5
print(f"🔥 {self.name} 施放火球术!造成 {damage:.0f} 点伤害")
return damage
else:
print(f"{self.name} 法力不足!")
return 0
class Healer(Character):
"""治疗者"""
def __init__(self, name, level=1):
super().__init__(name, level)
self.mana = 60 + (level - 1) * 15
self.max_mana = self.mana
def special_ability(self, target=None):
"""治疗术"""
if self.mana >= 15:
self.mana -= 15
heal_amount = self.max_hp * 0.3
if target:
target.heal(heal_amount)
print(f"✨ {self.name} 为 {target.name} 施放治疗术")
else:
self.heal(heal_amount)
print(f"✨ {self.name} 为自己施放治疗术")
return heal_amount
else:
print(f"{self.name} 法力不足!")
return 0
# 战斗系统
def battle(character1, character2):
"""回合制战斗"""
print(f"\n⚔️ 战斗开始: {character1.name} VS {character2.name}\n")
round_num = 1
while character1.hp > 0 and character2.hp > 0:
print(f"--- 第 {round_num} 回合 ---")
# 角色1行动
damage = character1.attack
defeated = character2.take_damage(damage)
if defeated:
character1.gain_experience(50)
break
# 角色2行动
damage = character2.attack
defeated = character1.take_damage(damage)
if defeated:
character2.gain_experience(50)
break
round_num += 1
print()
print("\n战斗结束\n")
# 使用示例
warrior = Warrior("亚瑟", level=5)
mage = Mage("梅林", level=5)
# 添加装备
sword = Weapon("圣剑", 500, 30)
staff = Weapon("法杖", 400, 20)
armor = Armor("铁甲", 300, 15)
warrior.add_item(sword)
warrior.add_item(armor)
mage.add_item(staff)
warrior.equip_weapon(sword)
warrior.equip_armor(armor)
mage.equip_weapon(staff)
warrior.show_status()
mage.show_status()
battle(warrior, mage)
实战3: 电商订单系统
from datetime import datetime
from enum import Enum
class OrderStatus(Enum):
"""订单状态枚举"""
PENDING = "待支付"
PAID = "已支付"
SHIPPED = "已发货"
DELIVERED = "已送达"
CANCELLED = "已取消"
class Product:
"""商品"""
def __init__(self, product_id, name, price, stock):
self.product_id = product_id
self.name = name
self.price = price
self.stock = stock
def reduce_stock(self, quantity):
"""减少库存"""
if quantity > self.stock:
raise ValueError(f"库存不足,仅剩 {self.stock} 件")
self.stock -= quantity
def __str__(self):
return f"{self.name} (¥{self.price:.2f}, 库存: {self.stock})"
class OrderItem:
"""订单项"""
def __init__(self, product, quantity):
self.product = product
self.quantity = quantity
@property
def subtotal(self):
return self.product.price * self.quantity
def __str__(self):
return f"{self.product.name} x{self.quantity} = ¥{self.subtotal:.2f}"
class Order:
"""订单"""
order_counter = 0 # 类属性:订单计数器
def __init__(self, customer_name):
Order.order_counter += 1
self.order_id = f"ORD{Order.order_counter:06d}"
self.customer_name = customer_name
self.items = []
self.status = OrderStatus.PENDING
self.created_at = datetime.now()
self.updated_at = self.created_at
def add_item(self, product, quantity=1):
"""添加商品到订单"""
if self.status != OrderStatus.PENDING:
raise ValueError("只能向待支付订单添加商品")
# 检查是否已存在相同商品
for item in self.items:
if item.product.product_id == product.product_id:
item.quantity += quantity
print(f"更新数量: {product.name} x{item.quantity}")
return
# 添加新商品
item = OrderItem(product, quantity)
self.items.append(item)
print(f"添加商品: {product.name} x{quantity}")
def remove_item(self, product_id):
"""移除商品"""
if self.status != OrderStatus.PENDING:
raise ValueError("只能从待支付订单移除商品")
self.items = [item for item in self.items
if item.product.product_id != product_id]
print(f"移除商品 ID: {product_id}")
@property
def total_amount(self):
"""订单总额"""
return sum(item.subtotal for item in self.items)
def pay(self):
"""支付订单"""
if self.status != OrderStatus.PENDING:
raise ValueError(f"订单状态不允许支付: {self.status.value}")
if not self.items:
raise ValueError("订单为空")
# 扣减库存
for item in self.items:
item.product.reduce_stock(item.quantity)
self.status = OrderStatus.PAID
self.updated_at = datetime.now()
print(f"✓ 订单 {self.order_id} 支付成功")
def ship(self):
"""发货"""
if self.status != OrderStatus.PAID:
raise ValueError(f"订单状态不允许发货: {self.status.value}")
self.status = OrderStatus.SHIPPED
self.updated_at = datetime.now()
print(f"✓ 订单 {self.order_id} 已发货")
def deliver(self):
"""送达"""
if self.status != OrderStatus.SHIPPED:
raise ValueError(f"订单状态不允许送达: {self.status.value}")
self.status = OrderStatus.DELIVERED
self.updated_at = datetime.now()
print(f"✓ 订单 {self.order_id} 已送达")
def cancel(self):
"""取消订单"""
if self.status not in [OrderStatus.PENDING, OrderStatus.PAID]:
raise ValueError(f"订单状态不允许取消: {self.status.value}")
# 恢复库存
if self.status == OrderStatus.PAID:
for item in self.items:
item.product.stock += item.quantity
self.status = OrderStatus.CANCELLED
self.updated_at = datetime.now()
print(f"✓ 订单 {self.order_id} 已取消")
def display_order(self):
"""显示订单详情"""
print(f"\n{'='*60}")
print(f"订单号: {self.order_id}")
print(f"客户: {self.customer_name}")
print(f"状态: {self.status.value}")
print(f"下单时间: {self.created_at}")
print(f"更新时间: {self.updated_at}")
print(f"{'-'*60}")
if self.items:
print("商品列表:")
for item in self.items:
print(f" {item}")
print(f"{'-'*60}")
print(f"总计: ¥{self.total_amount:.2f}")
else:
print("订单为空")
print(f"{'='*60}\n")
class ShoppingCart:
"""购物车"""
def __init__(self, customer_name):
self.customer_name = customer_name
self.items = {} # {product_id: {"product": product, "quantity": quantity}}
def add_product(self, product, quantity=1):
"""添加商品"""
if product.product_id in self.items:
self.items[product.product_id]["quantity"] += quantity
else:
self.items[product.product_id] = {
"product": product,
"quantity": quantity
}
print(f"加入购物车: {product.name} x{quantity}")
def remove_product(self, product_id):
"""移除商品"""
if product_id in self.items:
del self.items[product_id]
print(f"移除商品 ID: {product_id}")
def update_quantity(self, product_id, quantity):
"""更新数量"""
if product_id in self.items:
if quantity <= 0:
self.remove_product(product_id)
else:
self.items[product_id]["quantity"] = quantity
print(f"更新数量: {self.items[product_id]['product'].name} x{quantity}")
@property
def total_amount(self):
"""购物车总额"""
return sum(
item["product"].price * item["quantity"]
for item in self.items.values()
)
def checkout(self):
"""结算:创建订单"""
if not self.items:
raise ValueError("购物车为空")
order = Order(self.customer_name)
for item_data in self.items.values():
order.add_item(item_data["product"], item_data["quantity"])
# 清空购物车
self.items.clear()
print(f"✓ 结算成功,创建订单 {order.order_id}")
return order
def display_cart(self):
"""显示购物车"""
print(f"\n{'='*50}")
print(f"购物车 - {self.customer_name}")
print(f"{'-'*50}")
if self.items:
for item_data in self.items.values():
product = item_data["product"]
quantity = item_data["quantity"]
subtotal = product.price * quantity
print(f"{product.name} x{quantity} = ¥{subtotal:.2f}")
print(f"{'-'*50}")
print(f"总计: ¥{self.total_amount:.2f}")
else:
print("购物车为空")
print(f"{'='*50}\n")
# 使用示例
# 创建商品
product1 = Product("P001", "iPhone 15", 7999, 100)
product2 = Product("P002", "MacBook Pro", 14999, 50)
product3 = Product("P003", "AirPods", 1299, 200)
# 创建购物车
cart = ShoppingCart("张三")
cart.add_product(product1, 1)
cart.add_product(product3, 2)
cart.display_cart()
# 结算
order = cart.checkout()
order.display_order()
# 支付流程
order.pay()
order.ship()
order.deliver()
order.display_order()
常见错误与注意事项
1. 忘记调用父类构造函数
# ❌ 错误
class Child(Parent):
def __init__(self, name):
self.name = name
# 忘记调用 super().__init__()
# ✅ 正确
class Child(Parent):
def __init__(self, name):
super().__init__() # 先调用父类构造函数
self.name = name
2. 可变默认参数
# ❌ 危险
class Team:
def __init__(self, members=[]):
self.members = members
team1 = Team()
team2 = Team()
team1.members.append("Alice")
print(team2.members) # ['Alice'](共享了同一个列表!)
# ✅ 正确
class Team:
def __init__(self, members=None):
self.members = members or []
3. 混淆类属性和实例属性
# ❌ 错误
class Dog:
tricks = [] # 类属性,所有实例共享
def add_trick(self, trick):
self.tricks.append(trick)
dog1 = Dog()
dog2 = Dog()
dog1.add_trick("sit")
print(dog2.tricks) # ['sit'](不期望的结果)
# ✅ 正确
class Dog:
def __init__(self):
self.tricks = [] # 实例属性
def add_trick(self, trick):
self.tricks.append(trick)
4. 过度使用继承
# ❌ 不推荐:过深的继承层次
class Animal:
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class GoldenRetriever(Dog):
pass
# ✅ 推荐:使用组合
class Breed:
def __init__(self, name, characteristics):
self.name = name
self.characteristics = characteristics
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed # 组合而非继承
5. 滥用 getter/setter
# ❌ Java 风格(Python 中不必要)
class Person:
def __init__(self, name):
self._name = name
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
# ✅ Pythonic 风格
class Person:
def __init__(self, name):
self.name = name # 直接访问即可
# 需要验证时使用 @property
class Person:
def __init__(self, name):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not value:
raise ValueError("名字不能为空")
self._name = value
小结
| 概念 | 说明 | 使用场景 |
|---|---|---|
| 类和对象 | blueprint 和实例 | 组织相关数据和方法 |
| 构造函数 | __init__ 初始化对象 | 设置初始状态 |
| 实例方法 | 操作实例数据 | 对象的行为 |
| 类方法 | @classmethod 操作类 | 工厂方法、替代构造 |
| 静态方法 | @staticmethod 工具函数 | 与类相关但不依赖实例 |
| 封装 | 隐藏实现细节 | 保护数据完整性 |
| 继承 | 代码复用和扩展 | "是一个"关系 |
| 多态 | 同一接口不同实现 | 灵活的设计 |
| 魔术方法 | 自定义运算符和行为 | 让类更像内置类型 |
| 属性装饰器 | @property 管理属性 | 计算属性、验证 |
| 组合 | "有一个"关系 | 构建复杂对象 |
| 抽象基类 | ABC 定义接口 | 强制子类实现 |
核心要点:
- 面向对象是组织代码的强大工具
- 优先使用组合而非继承
- 遵循单一职责原则
- 合理使用封装保护数据
- 利用多态提高代码灵活性
- Python 推崇简洁优雅的 OOP 风格
- 理解魔术方法可以让类更 Pythonic
掌握面向对象编程将帮助你编写更清晰、可维护、可扩展的代码!