第9天-面向对象编程
哪吒 2023/6/15
# 第9天-Python面向对象编程
欢迎来到Python面向对象编程的世界!面向对象编程(Object-Oriented Programming,OOP)是一种强大的编程范式,它让我们能够创建更加模块化、可重用和易维护的代码。
# 什么是面向对象编程?
面向对象编程是一种编程范式,它将数据和操作数据的方法组织在一起,形成"对象"。这种方式更接近我们对现实世界的理解。
生活类比:
- 类(Class):像汽车的设计图纸,定义了汽车应该有什么属性和功能
- 对象(Object):像根据图纸制造出的具体汽车
- 属性(Attribute):像汽车的颜色、品牌、型号
- 方法(Method):像汽车的启动、加速、刹车功能
# OOP的四大特性
- 封装(Encapsulation):将数据和方法包装在一起,隐藏内部实现细节
- 继承(Inheritance):子类可以继承父类的属性和方法
- 多态(Polymorphism):同一个方法在不同类中有不同的实现
- 抽象(Abstraction):隐藏复杂的实现细节,只暴露必要的接口
# 一、类和对象基础
# 1.1 定义类
# 定义一个简单的学生类
class Student:
"""学生类
这个类用来表示一个学生,包含学生的基本信息和行为。
"""
# 类变量(所有实例共享)
school = "Python编程学院"
student_count = 0
def __init__(self, name, age, student_id):
"""构造方法(初始化方法)
Args:
name (str): 学生姓名
age (int): 学生年龄
student_id (str): 学号
"""
# 实例变量(每个实例独有)
self.name = name
self.age = age
self.student_id = student_id
self.grades = {} # 存储各科成绩
self.is_enrolled = True
# 每创建一个学生,计数器加1
Student.student_count += 1
def introduce(self):
"""自我介绍方法"""
return f"大家好,我是{self.name},今年{self.age}岁,学号是{self.student_id}"
def add_grade(self, subject, score):
"""添加成绩
Args:
subject (str): 科目名称
score (float): 成绩分数
"""
if 0 <= score <= 100:
self.grades[subject] = score
print(f"已为{self.name}添加{subject}成绩:{score}分")
else:
print("成绩必须在0-100之间")
def get_average_grade(self):
"""计算平均成绩
Returns:
float: 平均成绩,如果没有成绩则返回0
"""
if not self.grades:
return 0
return sum(self.grades.values()) / len(self.grades)
def get_grade_level(self):
"""根据平均成绩获取等级
Returns:
str: 成绩等级
"""
avg = self.get_average_grade()
if avg >= 90:
return "优秀"
elif avg >= 80:
return "良好"
elif avg >= 70:
return "中等"
elif avg >= 60:
return "及格"
else:
return "不及格"
def enroll(self):
"""注册入学"""
self.is_enrolled = True
print(f"{self.name}已成功注册入学")
def withdraw(self):
"""退学"""
self.is_enrolled = False
print(f"{self.name}已办理退学手续")
@classmethod
def get_student_count(cls):
"""类方法:获取学生总数
Returns:
int: 当前学生总数
"""
return cls.student_count
@classmethod
def create_from_string(cls, student_info):
"""类方法:从字符串创建学生对象
Args:
student_info (str): 格式为 "姓名,年龄,学号" 的字符串
Returns:
Student: 新创建的学生对象
"""
name, age, student_id = student_info.split(',')
return cls(name.strip(), int(age.strip()), student_id.strip())
@staticmethod
def is_valid_student_id(student_id):
"""静态方法:验证学号格式
Args:
student_id (str): 学号
Returns:
bool: 学号是否有效
"""
# 假设学号格式为:年份 + 4位数字
return len(student_id) == 8 and student_id.isdigit()
def __str__(self):
"""字符串表示方法"""
status = "在读" if self.is_enrolled else "已退学"
return f"学生({self.name}, {self.age}岁, {self.student_id}, {status})"
def __repr__(self):
"""开发者友好的字符串表示"""
return f"Student('{self.name}', {self.age}, '{self.student_id}')"
def __eq__(self, other):
"""相等性比较"""
if isinstance(other, Student):
return self.student_id == other.student_id
return False
def __lt__(self, other):
"""小于比较(按平均成绩)"""
if isinstance(other, Student):
return self.get_average_grade() < other.get_average_grade()
return NotImplemented
# 使用示例
print("=== 创建学生对象 ===")
# 创建学生对象
student1 = Student("张三", 20, "20230001")
student2 = Student("李四", 19, "20230002")
student3 = Student("王五", 21, "20230003")
print(student1)
print(student2)
print(student3)
print(f"\n当前学生总数:{Student.get_student_count()}")
print(f"学校名称:{Student.school}")
print("\n=== 学生自我介绍 ===")
print(student1.introduce())
print(student2.introduce())
print("\n=== 添加成绩 ===")
student1.add_grade("数学", 95)
student1.add_grade("英语", 87)
student1.add_grade("物理", 92)
student2.add_grade("数学", 78)
student2.add_grade("英语", 85)
student2.add_grade("物理", 80)
print(f"\n{student1.name}的平均成绩:{student1.get_average_grade():.2f}分,等级:{student1.get_grade_level()}")
print(f"{student2.name}的平均成绩:{student2.get_average_grade():.2f}分,等级:{student2.get_grade_level()}")
print("\n=== 使用类方法和静态方法 ===")
# 使用类方法创建学生
student4 = Student.create_from_string("赵六, 22, 20230004")
print(f"从字符串创建的学生:{student4}")
# 使用静态方法验证学号
print(f"学号20230001是否有效:{Student.is_valid_student_id('20230001')}")
print(f"学号123是否有效:{Student.is_valid_student_id('123')}")
print("\n=== 对象比较 ===")
print(f"student1 == student2: {student1 == student2}")
print(f"student1 < student2: {student1 < student2}")
# 1.2 属性访问控制
class BankAccount:
"""银行账户类 - 演示封装和属性访问控制"""
def __init__(self, account_number, owner_name, initial_balance=0):
self.account_number = account_number # 公开属性
self.owner_name = owner_name # 公开属性
self._balance = initial_balance # 受保护属性(约定:单下划线)
self.__pin = None # 私有属性(双下划线)
self.__transaction_history = [] # 私有属性
def set_pin(self, pin):
"""设置PIN码"""
if isinstance(pin, str) and len(pin) == 4 and pin.isdigit():
self.__pin = pin
print("PIN码设置成功")
else:
print("PIN码必须是4位数字")
def verify_pin(self, pin):
"""验证PIN码"""
return self.__pin == pin
def deposit(self, amount, pin):
"""存款"""
if not self.verify_pin(pin):
print("PIN码错误")
return False
if amount > 0:
self._balance += amount
self.__add_transaction("存款", amount)
print(f"存款成功,当前余额:{self._balance}元")
return True
else:
print("存款金额必须大于0")
return False
def withdraw(self, amount, pin):
"""取款"""
if not self.verify_pin(pin):
print("PIN码错误")
return False
if amount > 0 and amount <= self._balance:
self._balance -= amount
self.__add_transaction("取款", -amount)
print(f"取款成功,当前余额:{self._balance}元")
return True
else:
print("取款金额无效或余额不足")
return False
def get_balance(self, pin):
"""查询余额"""
if not self.verify_pin(pin):
print("PIN码错误")
return None
return self._balance
def get_transaction_history(self, pin):
"""获取交易历史"""
if not self.verify_pin(pin):
print("PIN码错误")
return None
return self.__transaction_history.copy()
def __add_transaction(self, transaction_type, amount):
"""私有方法:添加交易记录"""
from datetime import datetime
transaction = {
'type': transaction_type,
'amount': amount,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'balance_after': self._balance
}
self.__transaction_history.append(transaction)
def __str__(self):
return f"银行账户({self.account_number}, {self.owner_name})"
# 使用示例
print("=== 银行账户示例 ===")
account = BankAccount("6222001234567890", "张三", 1000)
print(account)
# 设置PIN码
account.set_pin("1234")
# 存款
account.deposit(500, "1234")
# 取款
account.withdraw(200, "1234")
# 查询余额
balance = account.get_balance("1234")
print(f"当前余额:{balance}元")
# 查看交易历史
history = account.get_transaction_history("1234")
print("\n交易历史:")
for transaction in history:
print(f"{transaction['timestamp']} - {transaction['type']}: {transaction['amount']}元, 余额: {transaction['balance_after']}元")
# 尝试直接访问私有属性(会失败)
print("\n=== 属性访问测试 ===")
print(f"公开属性 - 账户号码:{account.account_number}")
print(f"受保护属性 - 余额:{account._balance}")
# 尝试访问私有属性(Python会进行名称修饰)
try:
print(account.__pin) # 这会引发AttributeError
except AttributeError as e:
print(f"无法直接访问私有属性:{e}")
# 实际上私有属性被修饰为 _ClassName__attributeName
print(f"通过名称修饰访问私有属性:{account._BankAccount__pin}")
# 二、继承
# 2.1 基本继承
# 基类(父类)
class Animal:
"""动物基类"""
def __init__(self, name, species, age):
self.name = name
self.species = species
self.age = age
self.is_alive = True
def eat(self, food):
"""吃东西"""
print(f"{self.name}正在吃{food}")
def sleep(self):
"""睡觉"""
print(f"{self.name}正在睡觉")
def make_sound(self):
"""发出声音(基类中的通用实现)"""
print(f"{self.name}发出了声音")
def get_info(self):
"""获取动物信息"""
status = "活着" if self.is_alive else "已死亡"
return f"{self.name}是一只{self.age}岁的{self.species},目前{status}"
def __str__(self):
return f"{self.species}({self.name})"
# 派生类(子类)
class Dog(Animal):
"""狗类 - 继承自Animal"""
def __init__(self, name, breed, age, owner=None):
# 调用父类的构造方法
super().__init__(name, "狗", age)
self.breed = breed # 狗特有的属性
self.owner = owner
self.is_trained = False
def make_sound(self):
"""重写父类方法 - 狗的叫声"""
print(f"{self.name}汪汪叫")
def wag_tail(self):
"""狗特有的方法 - 摇尾巴"""
print(f"{self.name}开心地摇尾巴")
def fetch(self, item):
"""狗特有的方法 - 捡东西"""
print(f"{self.name}去捡{item}")
def train(self, command):
"""训练狗"""
print(f"正在训练{self.name}学习'{command}'命令")
self.is_trained = True
def get_info(self):
"""重写父类方法,添加狗特有信息"""
base_info = super().get_info()
breed_info = f",品种是{self.breed}"
owner_info = f",主人是{self.owner}" if self.owner else ",还没有主人"
training_info = f",{'已训练' if self.is_trained else '未训练'}"
return base_info + breed_info + owner_info + training_info
class Cat(Animal):
"""猫类 - 继承自Animal"""
def __init__(self, name, breed, age, is_indoor=True):
super().__init__(name, "猫", age)
self.breed = breed
self.is_indoor = is_indoor
self.lives_remaining = 9 # 猫有九条命
def make_sound(self):
"""重写父类方法 - 猫的叫声"""
print(f"{self.name}喵喵叫")
def purr(self):
"""猫特有的方法 - 呼噜声"""
print(f"{self.name}发出满足的呼噜声")
def climb(self, target):
"""猫特有的方法 - 爬高"""
print(f"{self.name}爬到了{target}上")
def hunt(self, prey):
"""猫特有的方法 - 狩猎"""
if not self.is_indoor:
print(f"{self.name}正在狩猎{prey}")
else:
print(f"{self.name}是室内猫,不能狩猎")
def lose_life(self):
"""失去一条命"""
if self.lives_remaining > 0:
self.lives_remaining -= 1
print(f"{self.name}失去了一条命,还剩{self.lives_remaining}条命")
if self.lives_remaining == 0:
self.is_alive = False
print(f"{self.name}用完了所有的命")
else:
print(f"{self.name}已经没有命了")
class Bird(Animal):
"""鸟类 - 继承自Animal"""
def __init__(self, name, species, age, can_fly=True):
super().__init__(name, species, age)
self.can_fly = can_fly
self.altitude = 0 # 当前高度
def make_sound(self):
"""重写父类方法 - 鸟的叫声"""
print(f"{self.name}啾啾叫")
def fly(self, height):
"""鸟特有的方法 - 飞行"""
if self.can_fly:
self.altitude = height
print(f"{self.name}飞到了{height}米高")
else:
print(f"{self.name}不会飞")
def land(self):
"""降落"""
if self.altitude > 0:
print(f"{self.name}从{self.altitude}米高降落到地面")
self.altitude = 0
else:
print(f"{self.name}已经在地面上了")
# 使用示例
print("=== 继承示例 ===")
# 创建不同类型的动物
dog = Dog("旺财", "金毛", 3, "张三")
cat = Cat("咪咪", "波斯猫", 2, True)
bird = Bird("小黄", "金丝雀", 1, True)
animals = [dog, cat, bird]
print("=== 所有动物的基本信息 ===")
for animal in animals:
print(animal.get_info())
print("\n=== 所有动物都会吃和睡 ===")
for animal in animals:
animal.eat("食物")
animal.sleep()
print("\n=== 多态:不同动物发出不同声音 ===")
for animal in animals:
animal.make_sound() # 每个子类都有自己的实现
print("\n=== 各种动物的特有行为 ===")
# 狗的特有行为
dog.wag_tail()
dog.fetch("球")
dog.train("坐下")
# 猫的特有行为
cat.purr()
cat.climb("书架")
cat.hunt("老鼠")
cat.lose_life()
# 鸟的特有行为
bird.fly(50)
bird.land()
print("\n=== 检查继承关系 ===")
print(f"dog是Animal的实例吗?{isinstance(dog, Animal)}")
print(f"dog是Dog的实例吗?{isinstance(dog, Dog)}")
print(f"dog是Cat的实例吗?{isinstance(dog, Cat)}")
print(f"Dog是Animal的子类吗?{issubclass(Dog, Animal)}")
print(f"Animal是Dog的子类吗?{issubclass(Animal, Dog)}")
# 2.2 多重继承
# 多重继承示例
class Flyable:
"""可飞行的混入类"""
def __init__(self):
self.max_altitude = 1000
self.current_altitude = 0
def take_off(self):
"""起飞"""
if self.current_altitude == 0:
self.current_altitude = 10
print(f"{self.name}起飞了,当前高度:{self.current_altitude}米")
else:
print(f"{self.name}已经在飞行中")
def fly_to_altitude(self, altitude):
"""飞到指定高度"""
if altitude <= self.max_altitude:
self.current_altitude = altitude
print(f"{self.name}飞到了{altitude}米高")
else:
print(f"{self.name}无法飞到{altitude}米,最大高度是{self.max_altitude}米")
def land(self):
"""降落"""
if self.current_altitude > 0:
print(f"{self.name}从{self.current_altitude}米高降落")
self.current_altitude = 0
else:
print(f"{self.name}已经在地面上")
class Swimmable:
"""可游泳的混入类"""
def __init__(self):
self.max_depth = 100
self.current_depth = 0
def dive(self, depth):
"""潜水"""
if depth <= self.max_depth:
self.current_depth = depth
print(f"{self.name}潜水到{depth}米深")
else:
print(f"{self.name}无法潜到{depth}米,最大深度是{self.max_depth}米")
def surface(self):
"""浮出水面"""
if self.current_depth > 0:
print(f"{self.name}从{self.current_depth}米深浮出水面")
self.current_depth = 0
else:
print(f"{self.name}已经在水面上")
def swim(self, direction):
"""游泳"""
print(f"{self.name}向{direction}游泳")
class Duck(Animal, Flyable, Swimmable):
"""鸭子类 - 多重继承示例"""
def __init__(self, name, age):
# 调用所有父类的构造方法
Animal.__init__(self, name, "鸭子", age)
Flyable.__init__(self)
Swimmable.__init__(self)
# 重新设置鸭子的特定限制
self.max_altitude = 500 # 鸭子飞不太高
self.max_depth = 5 # 鸭子潜不太深
def make_sound(self):
"""重写父类方法 - 鸭子的叫声"""
print(f"{self.name}嘎嘎叫")
def paddle(self):
"""鸭子特有的方法 - 划水"""
print(f"{self.name}用脚掌划水")
class Penguin(Animal, Swimmable):
"""企鹅类 - 不会飞但会游泳"""
def __init__(self, name, age):
Animal.__init__(self, name, "企鹅", age)
Swimmable.__init__(self)
self.max_depth = 200 # 企鹅游泳很厉害
def make_sound(self):
"""企鹅的叫声"""
print(f"{self.name}发出企鹅特有的叫声")
def slide_on_ice(self):
"""在冰上滑行"""
print(f"{self.name}在冰上滑行")
# 使用示例
print("\n=== 多重继承示例 ===")
duck = Duck("唐老鸭", 2)
penguin = Penguin("企鹅先生", 3)
print("=== 鸭子的能力 ===")
print(duck.get_info())
duck.make_sound()
# 鸭子可以飞
duck.take_off()
duck.fly_to_altitude(200)
duck.land()
# 鸭子可以游泳
duck.swim("前方")
duck.dive(3)
duck.paddle()
duck.surface()
print("\n=== 企鹅的能力 ===")
print(penguin.get_info())
penguin.make_sound()
# 企鹅不能飞,但可以游泳
penguin.swim("深海")
penguin.dive(50)
penguin.slide_on_ice()
penguin.surface()
print("\n=== 方法解析顺序(MRO) ===")
print(f"Duck的MRO:{Duck.__mro__}")
print(f"Penguin的MRO:{Penguin.__mro__}")
# 三、多态
# 3.1 方法重写和多态
# 多态示例:图形类
class Shape:
"""图形基类"""
def __init__(self, name):
self.name = name
def area(self):
"""计算面积 - 基类中的抽象方法"""
raise NotImplementedError("子类必须实现area方法")
def perimeter(self):
"""计算周长 - 基类中的抽象方法"""
raise NotImplementedError("子类必须实现perimeter方法")
def describe(self):
"""描述图形"""
return f"这是一个{self.name},面积:{self.area():.2f},周长:{self.perimeter():.2f}"
def __str__(self):
return f"{self.name}(面积: {self.area():.2f})"
class Rectangle(Shape):
"""矩形类"""
def __init__(self, width, height):
super().__init__("矩形")
self.width = width
self.height = height
def area(self):
"""矩形面积"""
return self.width * self.height
def perimeter(self):
"""矩形周长"""
return 2 * (self.width + self.height)
def is_square(self):
"""判断是否为正方形"""
return self.width == self.height
class Circle(Shape):
"""圆形类"""
def __init__(self, radius):
super().__init__("圆形")
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
def diameter(self):
"""直径"""
return 2 * self.radius
class Triangle(Shape):
"""三角形类"""
def __init__(self, side1, side2, side3):
super().__init__("三角形")
self.side1 = side1
self.side2 = side2
self.side3 = side3
# 验证是否能构成三角形
if not self._is_valid_triangle():
raise ValueError("无效的三角形边长")
def _is_valid_triangle(self):
"""验证三角形的有效性"""
return (self.side1 + self.side2 > self.side3 and
self.side1 + self.side3 > self.side2 and
self.side2 + self.side3 > self.side1)
def area(self):
"""三角形面积(海伦公式)"""
s = self.perimeter() / 2 # 半周长
import math
return math.sqrt(s * (s - self.side1) * (s - self.side2) * (s - self.side3))
def perimeter(self):
"""三角形周长"""
return self.side1 + self.side2 + self.side3
def triangle_type(self):
"""判断三角形类型"""
sides = sorted([self.side1, self.side2, self.side3])
if sides[0] == sides[1] == sides[2]:
return "等边三角形"
elif sides[0] == sides[1] or sides[1] == sides[2]:
return "等腰三角形"
else:
return "普通三角形"
# 多态函数
def calculate_total_area(shapes):
"""计算多个图形的总面积"""
total = 0
for shape in shapes:
total += shape.area() # 多态:每个图形都有自己的area实现
return total
def print_shape_info(shapes):
"""打印图形信息"""
for shape in shapes:
print(shape.describe()) # 多态:调用各自的area和perimeter方法
def find_largest_shape(shapes):
"""找到面积最大的图形"""
if not shapes:
return None
return max(shapes, key=lambda shape: shape.area())
# 使用示例
print("=== 多态示例 ===")
# 创建不同类型的图形
shapes = [
Rectangle(5, 3),
Circle(4),
Triangle(3, 4, 5),
Rectangle(2, 2), # 正方形
Circle(2.5)
]
print("=== 所有图形信息 ===")
print_shape_info(shapes)
print(f"\n=== 统计信息 ===")
print(f"图形总数:{len(shapes)}")
print(f"总面积:{calculate_total_area(shapes):.2f}")
largest = find_largest_shape(shapes)
print(f"面积最大的图形:{largest}")
print("\n=== 特定类型的操作 ===")
for shape in shapes:
if isinstance(shape, Rectangle):
if shape.is_square():
print(f"{shape.name}是正方形,边长:{shape.width}")
else:
print(f"{shape.name}的长宽比:{shape.width/shape.height:.2f}")
elif isinstance(shape, Circle):
print(f"{shape.name}的直径:{shape.diameter():.2f}")
elif isinstance(shape, Triangle):
print(f"{shape.name}的类型:{shape.triangle_type()}")
# 演示多态的威力
print("\n=== 多态演示 ===")
def process_shape(shape):
"""处理任意图形 - 不需要知道具体类型"""
print(f"处理{shape.name}:")
print(f" 面积: {shape.area():.2f}")
print(f" 周长: {shape.perimeter():.2f}")
# 根据面积大小给出评价
area = shape.area()
if area > 50:
print(" 这是一个大图形")
elif area > 20:
print(" 这是一个中等图形")
else:
print(" 这是一个小图形")
print()
for shape in shapes:
process_shape(shape) # 同一个函数处理不同类型的图形
# 3.2 抽象基类
from abc import ABC, abstractmethod
class Vehicle(ABC):
"""交通工具抽象基类"""
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.is_running = False
@abstractmethod
def start_engine(self):
"""启动引擎 - 抽象方法"""
pass
@abstractmethod
def stop_engine(self):
"""停止引擎 - 抽象方法"""
pass
@abstractmethod
def get_fuel_type(self):
"""获取燃料类型 - 抽象方法"""
pass
def get_info(self):
"""获取车辆信息 - 具体方法"""
status = "运行中" if self.is_running else "停止"
return f"{self.year}年 {self.brand} {self.model},当前状态:{status}"
def honk(self):
"""鸣笛 - 具体方法"""
print(f"{self.brand} {self.model}鸣笛:嘀嘀!")
class Car(Vehicle):
"""汽车类"""
def __init__(self, brand, model, year, doors=4):
super().__init__(brand, model, year)
self.doors = doors
self.fuel_level = 50 # 油量百分比
def start_engine(self):
"""启动汽车引擎"""
if not self.is_running:
if self.fuel_level > 0:
self.is_running = True
print(f"{self.brand} {self.model}引擎启动成功")
else:
print(f"{self.brand} {self.model}没有燃料,无法启动")
else:
print(f"{self.brand} {self.model}引擎已经在运行")
def stop_engine(self):
"""停止汽车引擎"""
if self.is_running:
self.is_running = False
print(f"{self.brand} {self.model}引擎已停止")
else:
print(f"{self.brand} {self.model}引擎已经停止")
def get_fuel_type(self):
"""获取燃料类型"""
return "汽油"
def refuel(self, amount):
"""加油"""
self.fuel_level = min(100, self.fuel_level + amount)
print(f"{self.brand} {self.model}加油完成,当前油量:{self.fuel_level}%")
def drive(self, distance):
"""驾驶"""
if self.is_running:
fuel_consumed = distance * 0.1 # 假设每公里消耗0.1%的油
if self.fuel_level >= fuel_consumed:
self.fuel_level -= fuel_consumed
print(f"{self.brand} {self.model}行驶了{distance}公里,剩余油量:{self.fuel_level:.1f}%")
else:
print(f"{self.brand} {self.model}燃料不足,无法行驶{distance}公里")
else:
print(f"{self.brand} {self.model}引擎未启动,无法行驶")
class ElectricCar(Vehicle):
"""电动汽车类"""
def __init__(self, brand, model, year, battery_capacity=100):
super().__init__(brand, model, year)
self.battery_capacity = battery_capacity # 电池容量(kWh)
self.battery_level = 80 # 电量百分比
def start_engine(self):
"""启动电动汽车"""
if not self.is_running:
if self.battery_level > 0:
self.is_running = True
print(f"{self.brand} {self.model}电动系统启动成功")
else:
print(f"{self.brand} {self.model}电池没电,无法启动")
else:
print(f"{self.brand} {self.model}电动系统已经在运行")
def stop_engine(self):
"""停止电动汽车"""
if self.is_running:
self.is_running = False
print(f"{self.brand} {self.model}电动系统已停止")
else:
print(f"{self.brand} {self.model}电动系统已经停止")
def get_fuel_type(self):
"""获取燃料类型"""
return "电力"
def charge(self, hours):
"""充电"""
charge_amount = hours * 10 # 假设每小时充电10%
self.battery_level = min(100, self.battery_level + charge_amount)
print(f"{self.brand} {self.model}充电{hours}小时,当前电量:{self.battery_level}%")
def drive(self, distance):
"""驾驶电动汽车"""
if self.is_running:
battery_consumed = distance * 0.2 # 假设每公里消耗0.2%的电
if self.battery_level >= battery_consumed:
self.battery_level -= battery_consumed
print(f"{self.brand} {self.model}行驶了{distance}公里,剩余电量:{self.battery_level:.1f}%")
else:
print(f"{self.brand} {self.model}电量不足,无法行驶{distance}公里")
else:
print(f"{self.brand} {self.model}电动系统未启动,无法行驶")
class Motorcycle(Vehicle):
"""摩托车类"""
def __init__(self, brand, model, year, engine_size):
super().__init__(brand, model, year)
self.engine_size = engine_size # 发动机排量
self.fuel_level = 30
def start_engine(self):
"""启动摩托车引擎"""
if not self.is_running:
if self.fuel_level > 0:
self.is_running = True
print(f"{self.brand} {self.model}摩托车引擎启动,轰鸣声响起")
else:
print(f"{self.brand} {self.model}没有燃料,无法启动")
else:
print(f"{self.brand} {self.model}引擎已经在运行")
def stop_engine(self):
"""停止摩托车引擎"""
if self.is_running:
self.is_running = False
print(f"{self.brand} {self.model}摩托车引擎已停止")
else:
print(f"{self.brand} {self.model}引擎已经停止")
def get_fuel_type(self):
"""获取燃料类型"""
return "汽油"
def wheelie(self):
"""摩托车特技 - 翘头"""
if self.is_running:
print(f"{self.brand} {self.model}做了一个精彩的翘头动作!")
else:
print(f"{self.brand} {self.model}需要先启动引擎")
# 多态函数
def start_all_vehicles(vehicles):
"""启动所有车辆"""
print("=== 启动所有车辆 ===")
for vehicle in vehicles:
vehicle.start_engine()
def show_vehicle_info(vehicles):
"""显示所有车辆信息"""
print("=== 车辆信息 ===")
for vehicle in vehicles:
print(f"{vehicle.get_info()},燃料类型:{vehicle.get_fuel_type()}")
def honk_all(vehicles):
"""所有车辆鸣笛"""
print("=== 集体鸣笛 ===")
for vehicle in vehicles:
vehicle.honk()
# 使用示例
print("=== 抽象基类和多态示例 ===")
# 创建不同类型的车辆
vehicles = [
Car("丰田", "卡罗拉", 2022),
ElectricCar("特斯拉", "Model 3", 2023, 75),
Motorcycle("本田", "CBR600RR", 2021, 600)
]
# 显示车辆信息
show_vehicle_info(vehicles)
# 启动所有车辆
start_all_vehicles(vehicles)
# 集体鸣笛
honk_all(vehicles)
print("\n=== 特定操作 ===")
# 汽车加油和行驶
car = vehicles[0]
car.refuel(20)
car.drive(50)
# 电动汽车充电和行驶
electric_car = vehicles[1]
electric_car.charge(2)
electric_car.drive(30)
# 摩托车特技
motorcycle = vehicles[2]
motorcycle.wheelie()
# 尝试创建抽象基类的实例(会报错)
try:
abstract_vehicle = Vehicle("测试", "测试", 2023)
except TypeError as e:
print(f"\n无法创建抽象基类的实例:{e}")
# 四、特殊方法(魔术方法)
# 4.1 常用特殊方法
class Money:
"""货币类 - 演示特殊方法的使用"""
def __init__(self, amount, currency="CNY"):
self.amount = amount
self.currency = currency
def __str__(self):
"""用户友好的字符串表示"""
currency_symbols = {
"CNY": "¥",
"USD": "$",
"EUR": "€",
"JPY": "¥"
}
symbol = currency_symbols.get(self.currency, self.currency)
return f"{symbol}{self.amount:.2f}"
def __repr__(self):
"""开发者友好的字符串表示"""
return f"Money({self.amount}, '{self.currency}')"
def __add__(self, other):
"""加法运算"""
if isinstance(other, Money):
if self.currency == other.currency:
return Money(self.amount + other.amount, self.currency)
else:
raise ValueError(f"不能将{self.currency}和{other.currency}直接相加")
elif isinstance(other, (int, float)):
return Money(self.amount + other, self.currency)
else:
return NotImplemented
def __radd__(self, other):
"""右加法运算(当左操作数不支持加法时)"""
return self.__add__(other)
def __sub__(self, other):
"""减法运算"""
if isinstance(other, Money):
if self.currency == other.currency:
return Money(self.amount - other.amount, self.currency)
else:
raise ValueError(f"不能将{self.currency}和{other.currency}直接相减")
elif isinstance(other, (int, float)):
return Money(self.amount - other, self.currency)
else:
return NotImplemented
def __mul__(self, other):
"""乘法运算"""
if isinstance(other, (int, float)):
return Money(self.amount * other, self.currency)
else:
return NotImplemented
def __rmul__(self, other):
"""右乘法运算"""
return self.__mul__(other)
def __truediv__(self, other):
"""除法运算"""
if isinstance(other, (int, float)):
if other != 0:
return Money(self.amount / other, self.currency)
else:
raise ZeroDivisionError("不能除以零")
else:
return NotImplemented
def __eq__(self, other):
"""相等比较"""
if isinstance(other, Money):
return self.amount == other.amount and self.currency == other.currency
return False
def __lt__(self, other):
"""小于比较"""
if isinstance(other, Money):
if self.currency == other.currency:
return self.amount < other.amount
else:
raise ValueError(f"不能比较{self.currency}和{other.currency}")
return NotImplemented
def __le__(self, other):
"""小于等于比较"""
return self == other or self < other
def __gt__(self, other):
"""大于比较"""
if isinstance(other, Money):
if self.currency == other.currency:
return self.amount > other.amount
else:
raise ValueError(f"不能比较{self.currency}和{other.currency}")
return NotImplemented
def __ge__(self, other):
"""大于等于比较"""
return self == other or self > other
def __hash__(self):
"""哈希值(使对象可以用作字典键或集合元素)"""
return hash((self.amount, self.currency))
def __bool__(self):
"""布尔值转换"""
return self.amount != 0
def __abs__(self):
"""绝对值"""
return Money(abs(self.amount), self.currency)
def __neg__(self):
"""负数"""
return Money(-self.amount, self.currency)
def __round__(self, ndigits=2):
"""四舍五入"""
return Money(round(self.amount, ndigits), self.currency)
class BankAccount:
"""银行账户类 - 演示容器特殊方法"""
def __init__(self, owner, initial_balance=0):
self.owner = owner
self.balance = Money(initial_balance)
self.transactions = [] # 交易记录
def deposit(self, amount):
"""存款"""
if isinstance(amount, (int, float)):
amount = Money(amount)
self.balance += amount
self.transactions.append(f"存款 {amount}")
def withdraw(self, amount):
"""取款"""
if isinstance(amount, (int, float)):
amount = Money(amount)
if amount <= self.balance:
self.balance -= amount
self.transactions.append(f"取款 {amount}")
else:
raise ValueError("余额不足")
def __len__(self):
"""返回交易记录数量"""
return len(self.transactions)
def __getitem__(self, index):
"""通过索引获取交易记录"""
return self.transactions[index]
def __setitem__(self, index, value):
"""通过索引设置交易记录"""
self.transactions[index] = value
def __delitem__(self, index):
"""通过索引删除交易记录"""
del self.transactions[index]
def __contains__(self, item):
"""检查是否包含某个交易记录"""
return item in self.transactions
def __iter__(self):
"""使对象可迭代"""
return iter(self.transactions)
def __str__(self):
return f"账户所有者:{self.owner},余额:{self.balance}"
def __repr__(self):
return f"BankAccount('{self.owner}', {self.balance.amount})"
# 使用示例
print("=== 特殊方法示例 ===")
# 创建货币对象
money1 = Money(100, "CNY")
money2 = Money(50, "CNY")
money3 = Money(75, "USD")
print("=== 基本操作 ===")
print(f"money1: {money1}")
print(f"money2: {money2}")
print(f"money3: {money3}")
print(f"repr(money1): {repr(money1)}")
print("\n=== 算术运算 ===")
print(f"money1 + money2 = {money1 + money2}")
print(f"money1 - money2 = {money1 - money2}")
print(f"money1 * 2 = {money1 * 2}")
print(f"3 * money2 = {3 * money2}")
print(f"money1 / 4 = {money1 / 4}")
print(f"money1 + 25 = {money1 + 25}")
print("\n=== 比较运算 ===")
print(f"money1 == money2: {money1 == money2}")
print(f"money1 > money2: {money1 > money2}")
print(f"money1 < money2: {money1 < money2}")
print("\n=== 其他运算 ===")
print(f"abs(Money(-50)): {abs(Money(-50))}")
print(f"-money1: {-money1}")
print(f"round(Money(123.456)): {round(Money(123.456))}")
print(f"bool(Money(0)): {bool(Money(0))}")
print(f"bool(money1): {bool(money1)}")
print("\n=== 银行账户示例 ===")
account = BankAccount("张三", 1000)
print(account)
# 进行一些交易
account.deposit(500)
account.withdraw(200)
account.deposit(Money(300))
print(f"\n交易记录数量:{len(account)}")
print("所有交易记录:")
for i, transaction in enumerate(account):
print(f"{i}: {transaction}")
print(f"\n第一笔交易:{account[0]}")
print(f"最后一笔交易:{account[-1]}")
print(f"是否包含'存款 ¥500.00':{'存款 ¥500.00' in account}")
# 货币对象可以用作字典键
print("\n=== 货币作为字典键 ===")
portfolio = {
Money(1000, "CNY"): "人民币储蓄",
Money(500, "USD"): "美元投资",
Money(200, "EUR"): "欧元基金"
}
for currency, description in portfolio.items():
print(f"{currency}: {description}")
# 尝试不同货币的运算(会报错)
try:
result = money1 + money3 # CNY + USD
except ValueError as e:
print(f"\n货币运算错误:{e}")
# 4.2 上下文管理器
class FileManager:
"""文件管理器 - 演示上下文管理器"""
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
"""进入上下文时调用"""
print(f"打开文件:{self.filename}")
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
"""退出上下文时调用"""
if self.file:
print(f"关闭文件:{self.filename}")
self.file.close()
# 处理异常
if exc_type is not None:
print(f"发生异常:{exc_type.__name__}: {exc_value}")
return False # 不抑制异常
return True
class DatabaseConnection:
"""数据库连接 - 另一个上下文管理器示例"""
def __init__(self, host, database):
self.host = host
self.database = database
self.connection = None
def __enter__(self):
"""建立数据库连接"""
print(f"连接到数据库:{self.host}/{self.database}")
# 这里模拟数据库连接
self.connection = f"Connection to {self.database}"
return self.connection
def __exit__(self, exc_type, exc_value, traceback):
"""关闭数据库连接"""
if self.connection:
print(f"关闭数据库连接:{self.database}")
self.connection = None
return False
# 使用示例
print("\n=== 上下文管理器示例 ===")
# 使用自定义文件管理器
try:
with FileManager("test.txt", "w") as f:
f.write("Hello, World!")
f.write("\nPython面向对象编程")
except FileNotFoundError:
print("文件操作完成(文件可能不存在,这是正常的)")
# 使用数据库连接管理器
with DatabaseConnection("localhost", "myapp") as conn:
print(f"使用连接:{conn}")
# 模拟数据库操作
print("执行SQL查询...")
print("连接已自动关闭")
# 五、属性装饰器
# 5.1 @property装饰器
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("温度不能低于绝对零度(-273.15°C)")
self._celsius = value
@property
def fahrenheit(self):
"""获取华氏温度"""
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
"""设置华氏温度"""
celsius = (value - 32) * 5/9
if celsius < -273.15:
raise ValueError("温度不能低于绝对零度")
self._celsius = celsius
@property
def kelvin(self):
"""获取开尔文温度"""
return self._celsius + 273.15
@kelvin.setter
def kelvin(self, value):
"""设置开尔文温度"""
if value < 0:
raise ValueError("开尔文温度不能为负数")
self._celsius = value - 273.15
def __str__(self):
return f"{self._celsius:.2f}°C ({self.fahrenheit:.2f}°F, {self.kelvin:.2f}K)"
class Circle:
"""圆形类 - 演示只读属性"""
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""半径(只读)"""
return self._radius
@property
def diameter(self):
"""直径(计算属性)"""
return self._radius * 2
@property
def area(self):
"""面积(计算属性)"""
import math
return math.pi * self._radius ** 2
@property
def circumference(self):
"""周长(计算属性)"""
import math
return 2 * math.pi * self._radius
def __str__(self):
return f"圆形(半径: {self.radius}, 直径: {self.diameter:.2f}, 面积: {self.area:.2f}, 周长: {self.circumference:.2f})"
class Person:
"""人员类 - 演示属性验证"""
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str) or len(value.strip()) == 0:
raise ValueError("姓名必须是非空字符串")
self._name = value.strip()
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int) or value < 0 or value > 150:
raise ValueError("年龄必须是0-150之间的整数")
self._age = value
@property
def email(self):
return self._email
@email.setter
def email(self, value):
if not isinstance(value, str) or '@' not in value:
raise ValueError("邮箱格式不正确")
self._email = value.lower()
@property
def is_adult(self):
"""是否成年(只读属性)"""
return self._age >= 18
@property
def age_group(self):
"""年龄组(只读属性)"""
if self._age < 13:
return "儿童"
elif self._age < 18:
return "青少年"
elif self._age < 60:
return "成年人"
else:
return "老年人"
def __str__(self):
return f"{self.name}({self.age}岁, {self.email}, {self.age_group})"
# 使用示例
print("=== 属性装饰器示例 ===")
# 温度转换
print("=== 温度转换 ===")
temp = Temperature(25)
print(f"初始温度:{temp}")
# 设置不同单位的温度
temp.fahrenheit = 100
print(f"设置华氏100度后:{temp}")
temp.kelvin = 300
print(f"设置开尔文300度后:{temp}")
# 尝试设置无效温度
try:
temp.celsius = -300
except ValueError as e:
print(f"温度设置错误:{e}")
# 圆形计算属性
print("\n=== 圆形计算属性 ===")
circle = Circle(5)
print(circle)
# 人员属性验证
print("\n=== 人员属性验证 ===")
try:
person = Person("张三", 25, "zhangsan@example.com")
print(person)
print(f"是否成年:{person.is_adult}")
# 修改属性
person.age = 17
print(f"修改年龄后:{person}")
print(f"是否成年:{person.is_adult}")
# 尝试设置无效邮箱
person.email = "invalid-email"
except ValueError as e:
print(f"属性设置错误:{e}")
# 六、实战练习
# 6.1 图书管理系统
from datetime import datetime, timedelta
class Book:
"""图书类"""
def __init__(self, isbn, title, author, publisher, price, total_copies=1):
self.isbn = isbn
self.title = title
self.author = author
self.publisher = publisher
self.price = price
self.total_copies = total_copies
self.available_copies = total_copies
self.borrowed_copies = 0
def borrow(self):
"""借书"""
if self.available_copies > 0:
self.available_copies -= 1
self.borrowed_copies += 1
return True
return False
def return_book(self):
"""还书"""
if self.borrowed_copies > 0:
self.available_copies += 1
self.borrowed_copies -= 1
return True
return False
@property
def is_available(self):
"""是否有可借阅的副本"""
return self.available_copies > 0
def __str__(self):
return f"《{self.title}》- {self.author} (可借: {self.available_copies}/{self.total_copies})"
def __repr__(self):
return f"Book('{self.isbn}', '{self.title}', '{self.author}')"
class Member:
"""会员类"""
def __init__(self, member_id, name, phone, email):
self.member_id = member_id
self.name = name
self.phone = phone
self.email = email
self.borrowed_books = [] # 当前借阅的书籍
self.borrow_history = [] # 借阅历史
self.join_date = datetime.now()
def can_borrow(self, max_books=5):
"""检查是否可以借书"""
return len(self.borrowed_books) < max_books
def borrow_book(self, book, due_days=30):
"""借书"""
if not self.can_borrow():
return False, "已达到最大借书数量"
if not book.is_available:
return False, "图书不可借阅"
if book.borrow():
borrow_record = {
'book': book,
'borrow_date': datetime.now(),
'due_date': datetime.now() + timedelta(days=due_days),
'returned': False
}
self.borrowed_books.append(borrow_record)
self.borrow_history.append(borrow_record)
return True, "借书成功"
return False, "借书失败"
def return_book(self, book):
"""还书"""
for record in self.borrowed_books:
if record['book'] == book and not record['returned']:
record['returned'] = True
record['return_date'] = datetime.now()
self.borrowed_books.remove(record)
book.return_book()
return True, "还书成功"
return False, "未找到借阅记录"
def get_overdue_books(self):
"""获取逾期图书"""
overdue = []
current_time = datetime.now()
for record in self.borrowed_books:
if current_time > record['due_date']:
overdue.append(record)
return overdue
def __str__(self):
return f"会员: {self.name} (ID: {self.member_id}, 当前借阅: {len(self.borrowed_books)}本)"
class Library:
"""图书馆类"""
def __init__(self, name):
self.name = name
self.books = {} # ISBN -> Book
self.members = {} # member_id -> Member
self.next_member_id = 1
def add_book(self, book):
"""添加图书"""
if book.isbn in self.books:
# 如果图书已存在,增加副本数
existing_book = self.books[book.isbn]
existing_book.total_copies += book.total_copies
existing_book.available_copies += book.available_copies
else:
self.books[book.isbn] = book
print(f"添加图书成功:{book}")
def register_member(self, name, phone, email):
"""注册会员"""
member_id = f"M{self.next_member_id:04d}"
member = Member(member_id, name, phone, email)
self.members[member_id] = member
self.next_member_id += 1
print(f"会员注册成功:{member}")
return member
def search_books(self, keyword):
"""搜索图书"""
results = []
keyword = keyword.lower()
for book in self.books.values():
if (keyword in book.title.lower() or
keyword in book.author.lower() or
keyword in book.publisher.lower()):
results.append(book)
return results
def borrow_book(self, member_id, isbn):
"""借书"""
if member_id not in self.members:
return False, "会员不存在"
if isbn not in self.books:
return False, "图书不存在"
member = self.members[member_id]
book = self.books[isbn]
return member.borrow_book(book)
def return_book(self, member_id, isbn):
"""还书"""
if member_id not in self.members:
return False, "会员不存在"
if isbn not in self.books:
return False, "图书不存在"
member = self.members[member_id]
book = self.books[isbn]
return member.return_book(book)
def get_overdue_report(self):
"""获取逾期报告"""
overdue_info = []
for member in self.members.values():
overdue_books = member.get_overdue_books()
if overdue_books:
overdue_info.append((member, overdue_books))
return overdue_info
def get_statistics(self):
"""获取统计信息"""
total_books = sum(book.total_copies for book in self.books.values())
available_books = sum(book.available_copies for book in self.books.values())
borrowed_books = total_books - available_books
return {
'total_books': total_books,
'available_books': available_books,
'borrowed_books': borrowed_books,
'total_members': len(self.members),
'unique_titles': len(self.books)
}
def __str__(self):
stats = self.get_statistics()
return f"{self.name} - 图书: {stats['unique_titles']}种/{stats['total_books']}本, 会员: {stats['total_members']}人"
# 使用示例
print("\n=== 图书管理系统示例 ===")
# 创建图书馆
library = Library("Python学习图书馆")
# 添加图书
books_data = [
("978-0-123456-78-9", "Python编程:从入门到实践", "埃里克·马瑟斯", "人民邮电出版社", 89.0, 3),
("978-0-987654-32-1", "流畅的Python", "Luciano Ramalho", "O'Reilly", 139.0, 2),
("978-0-111111-11-1", "Python核心编程", "Wesley Chun", "机械工业出版社", 99.0, 2),
("978-0-222222-22-2", "Python数据分析", "Wes McKinney", "机械工业出版社", 119.0, 1)
]
for isbn, title, author, publisher, price, copies in books_data:
book = Book(isbn, title, author, publisher, price, copies)
library.add_book(book)
print(f"\n{library}")
# 注册会员
members = [
library.register_member("张三", "13800138001", "zhangsan@example.com"),
library.register_member("李四", "13800138002", "lisi@example.com"),
library.register_member("王五", "13800138003", "wangwu@example.com")
]
# 搜索图书
print("\n=== 搜索图书 ===")
search_results = library.search_books("Python")
print(f"搜索'Python'的结果:")
for book in search_results:
print(f" {book}")
# 借书操作
print("\n=== 借书操作 ===")
borrow_operations = [
("M0001", "978-0-123456-78-9"),
("M0001", "978-0-987654-32-1"),
("M0002", "978-0-123456-78-9"),
("M0003", "978-0-111111-11-1")
]
for member_id, isbn in borrow_operations:
success, message = library.borrow_book(member_id, isbn)
member_name = library.members[member_id].name
book_title = library.books[isbn].title
print(f"{member_name} 借阅《{book_title}》: {message}")
# 显示会员借阅情况
print("\n=== 会员借阅情况 ===")
for member in library.members.values():
print(member)
for record in member.borrowed_books:
book = record['book']
due_date = record['due_date'].strftime('%Y-%m-%d')
print(f" - 《{book.title}》(到期日: {due_date})")
# 还书操作
print("\n=== 还书操作 ===")
success, message = library.return_book("M0001", "978-0-123456-78-9")
print(f"张三 归还《Python编程:从入门到实践》: {message}")
# 显示统计信息
print("\n=== 图书馆统计 ===")
stats = library.get_statistics()
for key, value in stats.items():
print(f"{key}: {value}")
# 七、总结
# 面向对象编程核心概念回顾
类和对象
- 类是对象的模板,对象是类的实例
- 使用
__init__
方法初始化对象 - 类变量和实例变量的区别
封装
- 使用私有属性(
__attribute
)隐藏内部实现 - 使用属性装饰器(
@property
)控制属性访问 - 提供公共接口操作私有数据
- 使用私有属性(
继承
- 子类继承父类的属性和方法
- 使用
super()
调用父类方法 - 方法重写实现多态
- 多重继承和MRO(方法解析顺序)
多态
- 同一接口,不同实现
- 抽象基类定义接口规范
- 运行时确定调用哪个方法
特殊方法
- 定制对象行为(
__str__
,__repr__
等) - 运算符重载(
__add__
,__eq__
等) - 上下文管理器(
__enter__
,__exit__
)
- 定制对象行为(
# 最佳实践
设计原则
- 单一职责:每个类只负责一个功能
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换:子类可以替换父类
- 依赖倒置:依赖抽象而不是具体实现
命名规范
- 类名使用大驼峰命名(PascalCase)
- 方法和属性使用小写加下划线(snake_case)
- 私有属性使用双下划线前缀
- 常量使用全大写加下划线
文档和测试
- 为类和方法编写清晰的文档字符串
- 使用类型注解提高代码可读性
- 编写单元测试验证功能正确性
# 下一步学习方向
设计模式
- 单例模式、工厂模式、观察者模式等
- 学习如何解决常见的设计问题
高级特性
- 元类(metaclass)
- 描述符(descriptor)
- 装饰器的高级用法
实际应用
- Web开发中的OOP应用
- 数据库ORM的设计
- GUI编程中的事件驱动
# 练习建议
基础练习
- 设计一个学生成绩管理系统
- 实现一个简单的银行账户系统
- 创建一个动物园管理系统
进阶练习
- 设计一个电商购物车系统
- 实现一个简单的游戏角色系统
- 创建一个文件管理器
项目实战
- 开发一个完整的图书管理系统
- 实现一个简单的博客系统
- 创建一个任务管理应用
面向对象编程是Python中非常重要的编程范式,掌握好OOP的概念和技巧,将为你后续学习更高级的Python特性和框架打下坚实的基础。记住,最好的学习方法就是多练习、多实践!