课程 20:类(Class)

课程目录

1. 类与对象基础

1.1 类和对象

类(Class): 就像是一个模板或蓝图,定义了某种事物的共同特征和行为。
对象(Object): 是根据类创建的具体实例,就像用模板制作出来的具体物品。

生活中的例子:
• 类:汽车设计图(定义汽车有轮子、发动机、能行驶等)
• 对象:具体的汽车(如我的红色宝马、你的白色丰田)

编程中的例子:
• 类:Student(定义学生有姓名、成绩、能显示信息等)
• 对象:具体的学生(如张三、李四等)

1.2 类的定义与实例化

# 定义类和创建对象
class Student:  # 定义类:Student 是类名
    def __init__(self, name, score):  # 构造方法:创建对象时自动调用
        self.name = name    # 实例属性:每个对象独有的数据
        self.score = score  # 实例属性:每个对象独有的数据
    
    def show_info(self):  # 实例方法:对象的行为
        print(f"学生姓名:{self.name},成绩:{self.score}")
    
    def get_grade(self):  # 实例方法:根据成绩返回等级
        if self.score >= 90:
            return "优秀"
        elif self.score >= 80:
            return "良好"
        elif self.score >= 60:
            return "及格"
        else:
            return "不及格"

# 创建对象:stu 是 Student 类的实例
stu = Student('Alice', 95)  # 调用构造方法,传入参数 'Alice' 和 95
print(stu.name, stu.score)  # 访问对象的属性
stu.show_info()  # 调用对象的方法
print(f"等级:{stu.get_grade()}")  # 调用方法并获取返回值
常用术语:
• 属性:对象的数据(如name、score)
• 方法:对象的行为(如show_score)
• 构造函数:__init__,用于初始化对象
• 析构函数:__del__,对象销毁时自动调用

2. 属性与方法细化

2.1 实例属性、类属性、私有属性

class Student:
    school = 'YunfanEdu'  # 类属性:所有实例共享,属于类本身
    def __init__(self, name, score):
        self.name = name      # 实例属性:每个对象独有的数据
        self._secret = '私有数据'  # 约定私有属性:下划线开头,约定为内部使用

# 创建对象
stu = Student('Bob', 88)

# 访问实例属性和类属性
print(stu.name, stu.school)  # 访问实例属性和类属性
print(stu._secret)  # 不建议外部访问私有属性

2.2 方法类型:实例方法、类方法、静态方法

class Demo:
    def instance_method(self):  # 实例方法:需要self参数,通过对象调用
        print('实例方法')
    
    @classmethod  # 装饰器:标记为类方法
    def class_method(cls):  # 类方法:需要cls参数,通过类调用
        print('类方法')
    
    @staticmethod  # 装饰器:标记为静态方法
    def static_method():  # 静态方法:不需要self或cls,通过类调用
        print('静态方法')

# 创建对象
d = Demo()

# 调用实例方法:需要对象
d.instance_method()  # 通过对象调用实例方法

# 调用类方法:通过类名调用
Demo.class_method()  # 通过类调用类方法

# 调用静态方法:通过类名调用
Demo.static_method()  # 通过类调用静态方法

2.3 属性封装与getter/setter

class Person:
    def __init__(self, age):
        self._age = age  # 私有属性:用下划线开头,约定为内部使用
    
    @property  # 装饰器:将方法转换为属性(getter)
    def age(self):  # getter方法:获取属性值
        return self._age
    
    @age.setter  # 装饰器:设置属性的setter方法
    def age(self, value):  # setter方法:设置属性值,可以添加验证
        if value < 0:
            raise ValueError('年龄不能为负')  # 数据验证:防止无效数据
        self._age = value

# 创建对象
p = Person(18)  # 初始化年龄为18

# 使用属性:看起来像普通属性,实际调用了方法
p.age = 20  # 调用setter方法,设置年龄为20
print(p.age)  # 调用getter方法,获取年龄值
建议: 用@property保护属性安全,便于后期维护和扩展。

3. 魔法方法与调试技巧

3.1 __str__、__repr__、__eq__等

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def __str__(self):  # 魔法方法:定义对象的字符串表示(用户友好)
        return f"Student({self.name}, {self.score})"
    
    def __eq__(self, other):  # 魔法方法:定义对象相等性比较
        return self.name == other.name and self.score == other.score

# 创建两个相同的学生对象
stu1 = Student('Alice', 95)
stu2 = Student('Alice', 95)

# 测试魔法方法
print(stu1)  # 调用__str__方法,输出友好的字符串表示
print(stu1 == stu2)  # 调用__eq__方法,比较两个对象是否相等
调试技巧: __str__和__repr__便于打印对象,__eq__等便于对象比较。

4. 继承、多态、组合与高级OOP

4.1 继承与super()

class Animal:  # 父类(基类)
    def speak(self):
        print('动物叫')

class Dog(Animal):  # 子类:继承父类Animal
    def speak(self):  # 重写父类方法
        super().speak()  # 调用父类方法
        print('汪汪!')  # 添加子类特有的行为

# 创建子类对象
d = Dog()
d.speak()  # 调用重写后的方法

4.2 多态与鸭子类型

class Cat:  # 另一个类,也有speak方法
    def speak(self):
        print('喵喵!')

def animal_speak(animal):  # 多态函数:接受任何有speak方法的对象
    animal.speak()  # 调用对象的speak方法

# 多态演示:不同对象调用相同接口,产生不同结果
for a in [Dog(), Cat()]:  # 创建不同类型的对象
    animal_speak(a)  # 多态:同一函数处理不同类型对象

4.3 组合与MRO

class Engine:  # 发动机类
    def start(self):
        print('发动机启动')

class Car:  # 汽车类
    def __init__(self):
        self.engine = Engine()  # 组合:汽车包含发动机对象
    
    def drive(self):
        self.engine.start()  # 通过组合对象调用方法
        print('汽车行驶')

# 创建汽车对象
car = Car()
car.drive()  # 调用汽车方法,内部使用发动机

# 查看方法解析顺序(MRO)
print(Car.__mro__)  # 显示类的继承顺序
OOP进阶: 组合优于继承,MRO(方法解析顺序)影响多重继承下方法调用。

5. 类的实际应用案例

5.1 学生成绩管理

class Student:
    def __init__(self, name):
        self.name = name
        self.scores = {}  # 用字典存储多门课程成绩
    
    def add_score(self, subject, score):  # 添加成绩方法
        self.scores[subject] = score
    
    def show_all(self):  # 显示所有成绩方法
        print(f"{self.name}的成绩:")
        for subject, score in self.scores.items():
            print(f"  {subject}: {score}")

# 创建学生对象并管理成绩
stu = Student('Alice')
stu.add_score('Math', 95)  # 添加数学成绩
stu.add_score('English', 88)  # 添加英语成绩
stu.show_all()  # 显示所有成绩

5.2 银行账户与工厂模式

class Account:  # 银行账户类
    def __init__(self, owner, balance=0):
        self.owner = owner  # 账户持有人
        self.balance = balance  # 账户余额
    
    def deposit(self, amount):  # 存款方法
        self.balance += amount
    
    def withdraw(self, amount):  # 取款方法
        if amount > self.balance:
            print('余额不足')
        else:
            self.balance -= amount

class AccountFactory:  # 工厂类:负责创建账户对象
    @staticmethod
    def create_account(owner):  # 静态方法:创建账户
        return Account(owner)

# 使用工厂模式创建账户
acc = AccountFactory.create_account('Tom')
acc.deposit(100)  # 存款100
print(acc.balance)  # 查看余额

5.3 图形类与方法扩展

class Rectangle:  # 矩形类
    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)
    
    def is_square(self):  # 判断是否为正方形方法
        return self.width == self.height

# 创建矩形对象并测试方法
rect = Rectangle(3, 4)
print('面积:', rect.area())  # 计算并输出面积
print('周长:', rect.perimeter())  # 计算并输出周长
print('是否正方形:', rect.is_square())  # 判断并输出是否为正方形
实际应用: 类常用于建模现实世界对象、管理数据、实现复杂逻辑、封装第三方库、设计模式等。
学习建议:类是OOP的基础,建议多动手实践,理解属性、方法、继承、多态、组合、设计模式等核心概念,遇到报错要学会调试和查文档。推荐多用__str__/__repr__、isinstance、UML等工具辅助调试和设计。
思考题:类和对象的区别是什么?如何设计一个高内聚、低耦合的类?OOP有哪些常见误区,如何避免?组合和继承如何选择?UML类图在设计中的作用?