← 返回首页 | ← 返回教程列表

Python学习教程 - 第七课:面向对象编程,创建你的世界!

欢迎回来!🎉 这节课我们要学习面向对象编程(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()

关键点说明


第三个知识点:属性和方法

实例属性和类属性

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)  # 报错,私有属性不能直接访问

使用@property装饰器

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__等特殊方法


课后练习 ✏️

  1. 创建一个简单的银行账户类,支持存款、取款、查询余额
  2. 创建一个学生类,继承自Person类,添加学号、成绩等属性
  3. 创建一个图形类层次结构(圆形、矩形、三角形),实现面积计算
  4. 使用魔术方法创建一个复数类,支持加减乘除运算
  5. 创建一个简单的购物车类,支持添加商品、删除商品、计算总价

下节课预告:我们会学习异常和错误处理,让程序更健壮!

继续加油!你已经掌握了Python编程的核心技能!💪