欢迎回来!🎉 这节课我们要学习面向对象编程(Object-Oriented Programming,简称OOP)—— 一种强大的编程范式,让你可以创建自己的"世界"!
前六节课我们学会了: - 变量和基本数据类型 - 条件判断和循环 - 列表和字典 - 函数(代码的魔法师) - 文件操作(数据持久化) - 模块和包(代码组织)
这节课我们要学习一种全新的编程思维方式!
过程式编程:关注"怎么做",用函数来完成任务
面向对象编程:关注"谁来做",用对象来组织代码
对象 = 属性 + 方法
| 对象 | 属性 | 方法 |
|---|---|---|
| 猫 | 颜色、年龄、品种 | 叫、跳、抓老鼠 |
| 汽车 | 品牌、颜色、速度 | 启动、加速、刹车 |
| 学生 | 姓名、年龄、学号 | 学习、考试、休息 |
类是对象的蓝图或模板,定义了对象应该有什么属性和方法。
对象是类的实例,是具体的"东西"。
# 定义一个Person类
class Person:
# 初始化方法(构造函数)
def __init__(self, name, age):
# 属性
self.name = name
self.age = age
# 方法
def greet(self):
print(f"你好,我是{self.name},今年{self.age}岁!")
def celebrate_birthday(self):
self.age += 1
print(f"生日快乐!{self.name}现在{self.age}岁了!")
# 创建对象(实例化)
person1 = Person("小明", 18)
person2 = Person("小红", 17)
# 使用对象
person1.greet()
person2.greet()
person1.celebrate_birthday()
person1.greet()
__init__:初始化方法,创建对象时自动调用self:指向对象自己的引用,必须是第一个参数person1、person2:Person类的实例(对象)class Student:
# 类属性:所有实例共享
school = "Python中学"
def __init__(self, name, student_id):
# 实例属性:每个实例独有
self.name = name
self.student_id = student_id
self.grades = []
def add_grade(self, grade):
self.grades.append(grade)
def get_average_grade(self):
if self.grades:
return sum(self.grades) / len(self.grades)
return 0
# 创建学生
student1 = Student("小明", "2024001")
student2 = Student("小红", "2024002")
# 访问实例属性
student1.add_grade(90)
student1.add_grade(85)
print(f"{student1.name}的平均分:{student1.get_average_grade()}")
# 访问类属性
print(f"{student1.name}的学校:{student1.school}")
print(f"{student2.name}的学校:{student2.school}")
# 修改类属性(会影响所有实例)
Student.school = "编程大学"
print(f"{student1.name}的新学校:{student1.school}")
print(f"{student2.name}的新学校:{student2.school}")
class Math:
# 实例方法
def add(self, a, b):
return a + b
# 类方法
@classmethod
def multiply(cls, a, b):
return a * b
# 静态方法
@staticmethod
def subtract(a, b):
return a - b
# 使用
math_obj = Math()
print("实例方法:", math_obj.add(3, 5))
print("类方法:", Math.multiply(4, 6))
print("静态方法:", Math.subtract(10, 3))
封装就是把数据(属性)和操作数据的方法绑定在一起,并隐藏内部细节,只暴露必要的接口。
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self._balance = balance # 单下划线:约定为"受保护"
self.__secret_code = "1234" # 双下划线:私有属性(名称改写)
def deposit(self, amount):
"""存款"""
if amount > 0:
self._balance += amount
print(f"存款成功!余额:{self._balance}")
else:
print("存款金额必须大于0!")
def withdraw(self, amount):
"""取款"""
if 0 < amount <= self._balance:
self._balance -= amount
print(f"取款成功!余额:{self._balance}")
else:
print("取款金额无效或余额不足!")
def get_balance(self):
"""获取余额"""
return self._balance
# 使用
account = BankAccount("小明", 1000)
account.deposit(500)
account.withdraw(300)
print(f"余额:{account.get_balance()}")
# 尝试直接访问(不推荐)
print(account._balance) # 可以访问,但约定上不要这样做
# print(account.__secret_code) # 报错,私有属性不能直接访问
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
"""获取摄氏温度"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""设置摄氏温度"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度!")
self._celsius = value
@property
def fahrenheit(self):
"""获取华氏温度"""
return self._celsius * 9/5 + 32
# 使用
temp = Temperature(25)
print(f"摄氏温度:{temp.celsius}°C")
print(f"华氏温度:{temp.fahrenheit}°F")
temp.celsius = 30
print(f"新的摄氏温度:{temp.celsius}°C")
print(f"新的华氏温度:{temp.fahrenheit}°F")
继承就是一个类(子类)继承另一个类(父类)的属性和方法,实现代码复用和扩展。
# 父类(基类)
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(f"{self.name}正在吃东西...")
def sleep(self):
print(f"{self.name}正在睡觉...")
# 子类(派生类)
class Dog(Animal):
def __init__(self, name, age, breed):
# 调用父类的初始化方法
super().__init__(name, age)
self.breed = breed
def bark(self):
print(f"{self.name}在汪汪叫!")
# 重写父类方法
def eat(self):
print(f"{self.name}({self.breed})正在吃狗粮!")
class Cat(Animal):
def __init__(self, name, age, color):
super().__init__(name, age)
self.color = color
def meow(self):
print(f"{self.name}在喵喵叫!")
# 使用
dog = Dog("旺财", 3, "金毛")
cat = Cat("咪咪", 2, "白色")
dog.eat()
dog.bark()
dog.sleep()
cat.eat()
cat.meow()
cat.sleep()
class Vehicle:
def __init__(self, brand):
self.brand = brand
def move(self):
print(f"{self.brand}正在移动...")
class Car(Vehicle):
def __init__(self, brand, model):
super().__init__(brand)
self.model = model
def drive(self):
print(f"{self.brand} {self.model}正在行驶...")
class ElectricCar(Car):
def __init__(self, brand, model, battery_capacity):
super().__init__(brand, model)
self.battery_capacity = battery_capacity
def charge(self):
print(f"{self.brand} {self.model}正在充电,电池容量:{self.battery_capacity}kWh")
# 重写方法
def move(self):
print(f"{self.brand} {self.model}正在安静地行驶(电动)...")
# 使用
tesla = ElectricCar("特斯拉", "Model 3", 75)
tesla.move()
tesla.drive()
tesla.charge()
多态就是不同的对象对同一个方法调用有不同的响应。
class Shape:
def area(self):
"""计算面积(子类需要重写)"""
raise NotImplementedError("子类必须重写这个方法")
def perimeter(self):
"""计算周长(子类需要重写)"""
raise NotImplementedError("子类必须重写这个方法")
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
class Triangle(Shape):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def area(self):
# 海伦公式
s = (self.a + self.b + self.c) / 2
import math
return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
def perimeter(self):
return self.a + self.b + self.c
# 多态演示
shapes = [
Rectangle(5, 3),
Circle(4),
Triangle(3, 4, 5)
]
print("=== 计算各种图形的面积和周长 ===")
for shape in shapes:
print(f"{shape.__class__.__name__}:")
print(f" 面积: {shape.area():.2f}")
print(f" 周长: {shape.perimeter():.2f}")
魔术方法是Python中以双下划线开头和结尾的特殊方法,它们会在特定情况下被自动调用。
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
# 字符串表示
def __str__(self):
"""用户友好的字符串表示"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""开发者友好的字符串表示"""
return f"Vector(x={self.x}, y={self.y})"
# 运算符重载
def __add__(self, other):
"""加法:v1 + v2"""
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
"""减法:v1 - v2"""
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
"""乘法:v * 3"""
return Vector(self.x * scalar, self.y * scalar)
# 比较运算
def __eq__(self, other):
"""相等:v1 == v2"""
return self.x == other.x and self.y == other.y
def __lt__(self, other):
"""小于:v1 < v2(比较模长)"""
return self.magnitude() < other.magnitude()
# 长度
def __len__(self):
"""len(v)"""
return 2 # 二维向量
# 索引访问
def __getitem__(self, index):
"""v[0], v[1]"""
if index == 0:
return self.x
elif index == 1:
return self.y
raise IndexError("向量索引超出范围")
# 调用
def __call__(self):
"""v()"""
print(f"向量被调用:{self}")
# 自定义方法
def magnitude(self):
"""计算模长"""
import math
return math.sqrt(self.x ** 2 + self.y ** 2)
# 使用
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print("v1:", v1)
print("repr(v1):", repr(v1))
print("len(v1):", len(v1))
print("v1[0]:", v1[0])
print("v1[1]:", v1[1])
v3 = v1 + v2
print("v1 + v2 =", v3)
v4 = v1 - v2
print("v1 - v2 =", v4)
v5 = v1 * 2
print("v1 * 2 =", v5)
print("v1 == v2:", v1 == v2)
print("v1 < v2:", v1 < v2)
print("v1的模长:", v1.magnitude())
v1() # 调用
让我们创建一个完整的游戏角色系统!
import random
from abc import ABC, abstractmethod
# 抽象基类
class Character(ABC):
def __init__(self, name, hp, attack, defense):
self.name = name
self.max_hp = hp
self.current_hp = hp
self.attack = attack
self.defense = defense
self.level = 1
self.exp = 0
self.skills = []
@abstractmethod
def special_attack(self, target):
"""特殊攻击(子类必须实现)"""
pass
def normal_attack(self, target):
"""普通攻击"""
damage = max(1, self.attack - target.defense // 2 + random.randint(-3, 3))
target.current_hp -= damage
print(f"{self.name}对{target.name}发动普通攻击,造成{damage}点伤害!")
def take_damage(self, damage):
"""受到伤害"""
actual_damage = max(1, damage - self.defense)
self.current_hp -= actual_damage
print(f"{self.name}受到{actual_damage}点伤害!剩余HP:{max(0, self.current_hp)}")
def heal(self, amount):
"""治疗"""
healed = min(amount, self.max_hp - self.current_hp)
self.current_hp += healed
print(f"{self.name}恢复了{healed}点HP!当前HP:{self.current_hp}")
def gain_exp(self, amount):
"""获得经验"""
self.exp += amount
print(f"{self.name}获得了{amount}点经验!")
# 检查是否升级
exp_needed = self.level * 100
while self.exp >= exp_needed:
self.level_up()
exp_needed = self.level * 100
def level_up(self):
"""升级"""
self.level += 1
self.max_hp += 20
self.current_hp = self.max_hp
self.attack += 5
self.defense += 3
print(f"\n🎉 {self.name}升级了!现在是{self.level}级!")
print(f" HP上限:{self.max_hp},攻击:{self.attack},防御:{self.defense}")
def is_alive(self):
"""是否存活"""
return self.current_hp > 0
def __str__(self):
return f"{self.name} (Lv.{self.level}) - HP: {self.current_hp}/{self.max_hp} - ATK: {self.attack} - DEF: {self.defense}"
# 战士类
class Warrior(Character):
def __init__(self, name):
super().__init__(name, hp=120, attack=15, defense=10)
def special_attack(self, target):
"""重击"""
damage = int(self.attack * 1.8) - target.defense // 2
damage = max(1, damage + random.randint(-2, 5))
target.current_hp -= damage
print(f"⚔️ {self.name}发动重击!对{target.name}造成{damage}点伤害!")
# 法师类
class Mage(Character):
def __init__(self, name):
super().__init__(name, hp=80, attack=20, defense=5)
self.mana = 100
self.max_mana = 100
def special_attack(self, target):
"""火球术"""
if self.mana >= 20:
self.mana -= 20
damage = int(self.attack * 2.0) + random.randint(0, 10)
target.current_hp -= damage
print(f"🔥 {self.name}释放火球术!对{target.name}造成{damage}点伤害!")
else:
print(f"{self.name}的魔力不足!")
def recharge_mana(self):
"""恢复魔力"""
recovered = min(30, self.max_mana - self.mana)
self.mana += recovered
print(f"{self.name}恢复了{recovered}点魔力!")
# 治疗师类
class Healer(Character):
def __init__(self, name):
super().__init__(name, hp=90, attack=10, defense=8)
def special_attack(self, target):
"""治疗术(治疗自己或队友)"""
heal_amount = 30 + random.randint(5, 15)
target.heal(heal_amount)
print(f"💚 {self.name}对{target.name}使用治疗术!")
# 战斗系统
class BattleSystem:
@staticmethod
def battle(character1, character2):
"""两个角色战斗"""
print(f"\n{'='*60}")
print(f"⚔️ 战斗开始:{character1.name} VS {character2.name}")
print(f"{'='*60}\n")
turn = 1
while character1.is_alive() and character2.is_alive():
print(f"--- 第{turn}回合 ---")
print(character1)
print(character2)
print()
# 角色1攻击
if character1.is_alive():
if random.random() < 0.3: # 30%几率使用特殊攻击
character1.special_attack(character2)
else:
character1.normal_attack(character2)
print()
# 角色2攻击
if character2.is_alive():
if random.random() < 0.3:
character2.special_attack(character1)
else:
character2.normal_attack(character1)
print()
turn += 1
# 战斗结束
print(f"{'='*60}")
if character1.is_alive():
print(f"🎉 {character1.name}获胜!")
character1.gain_exp(50)
else:
print(f"🎉 {character2.name}获胜!")
character2.gain_exp(50)
print(f"{'='*60}\n")
# 测试游戏
if __name__ == "__main__":
print("🎮 欢迎来到RPG游戏!\n")
# 创建角色
warrior = Warrior("勇者小明")
mage = Mage("法师小红")
healer = Healer("治疗师小刚")
# 显示角色信息
print("=== 角色创建完成 ===")
print(warrior)
print(mage)
print(healer)
print()
# 进行战斗
BattleSystem.battle(warrior, mage)
BattleSystem.battle(warrior, healer)
BattleSystem.battle(mage, healer)
今天我们学会了:
✅ 面向对象编程:关注"谁来做"而不是"怎么做"
✅ 类和对象:类是蓝图,对象是实例
✅ 属性和方法:实例属性、类属性,实例方法、类方法、静态方法
✅ 封装:隐藏内部细节,只暴露必要接口
✅ 继承:子类继承父类,实现代码复用
✅ 多态:不同对象对同一方法有不同响应
✅ 魔术方法:__init__、__str__、__add__等特殊方法
下节课预告:我们会学习异常和错误处理,让程序更健壮!
继续加油!你已经掌握了Python编程的核心技能!💪