课程 21:类的进阶

学习目标

1. 继承、super()与MRO

1.1 多层继承与super()

class Animal:
    def speak(self):
        print('动物叫')
class Mammal(Animal):
    def speak(self):
        print('哺乳动物叫')
class Dog(Mammal):
    def speak(self):
        super().speak()
        print('狗叫')
d = Dog()
d.speak()

1.2 MRO与多重继承

class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print(D.__mro__)
方法解析顺序(MRO): 决定多重继承下方法的查找顺序。super()遵循MRO。

1.3 组合与继承对比

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()
建议: 组合优于继承,优先用组合实现“有一个”,继承实现“是一个”。

2. 多态、鸭子类型与抽象基类

2.1 多态与鸭子类型

class Cat:
    def speak(self):
        print('喵喵!')
def animal_speak(animal):
    animal.speak()
for a in [Dog(), Cat()]:
    animal_speak(a)

2.2 抽象基类与接口设计

from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w
        self.h = h
    def area(self):
        return self.w * self.h
# s = Shape()  # TypeError: Can't instantiate abstract class
接口设计: 用抽象基类强制子类实现接口,便于统一和扩展。

2.3 类型检查与isinstance

print(isinstance(Rectangle(1,2), Shape))

3. 类方法、静态方法与设计模式

3.1 工厂方法与单例模式

class Account:
    def __init__(self, owner):
        self.owner = owner
    @classmethod
    def create(cls, owner):
        return cls(owner)
class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

3.2 静态方法实际应用

class Math:
    @staticmethod
    def add(a, b):
        return a + b
print(Math.add(3, 5))
实际应用: 工厂方法用于批量创建对象,单例模式保证全局唯一实例。

4. 魔法方法与容器协议

4.1 常用魔法方法与协议

class MyList:
    def __init__(self):
        self.data = []
    def __getitem__(self, idx):
        return self.data[idx]
    def __setitem__(self, idx, value):
        self.data[idx] = value
    def __len__(self):
        return len(self.data)
    def __iter__(self):
        return iter(self.data)
    def __contains__(self, item):
        return item in self.data
    def append(self, value):
        self.data.append(value)
lst = MyList()
lst.append(10)
lst.append(20)
print(lst[0], len(lst), 10 in lst)
for x in lst:
    print(x)

4.2 只读容器与缓存

class ReadOnlyList:
    def __init__(self, data):
        self._data = list(data)
    def __getitem__(self, idx):
        return self._data[idx]
    def __len__(self):
        return len(self._data)
    def __setitem__(self, idx, value):
        raise TypeError('只读容器不允许修改')
rol = ReadOnlyList([1,2,3])
print(rol[0], len(rol))
# rol[0] = 10  # TypeError

4.3 生成器与for循环协议

class Fib:
    def __init__(self, n):
        self.n = n
    def __iter__(self):
        self.a, self.b, self.count = 0, 1, 0
        return self
    def __next__(self):
        if self.count < self.n:
            val = self.a
            self.a, self.b = self.b, self.a + self.b
            self.count += 1
            return val
        else:
            raise StopIteration
for x in Fib(5):
    print(x)
协议: 容器协议(__getitem__、__len__、__contains__),迭代器协议(__iter__、__next__)。

5. 实际应用案例

5.1 插件系统与扩展

class PluginBase(ABC):
    @abstractmethod
    def run(self): pass
class PluginA(PluginBase):
    def run(self): print('A插件')
class PluginB(PluginBase):
    def run(self): print('B插件')
plugins = [PluginA(), PluginB()]
for p in plugins:
    p.run()

5.2 LRU缓存容器

from collections import OrderedDict
class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict()
        self.capacity = capacity
    def get(self, key):
        if key in self.cache:
            self.cache.move_to_end(key)
            return self.cache[key]
        return -1
    def put(self, key, value):
        self.cache[key] = value
        self.cache.move_to_end(key)
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)
lru = LRUCache(2)
lru.put('a', 1)
lru.put('b', 2)
lru.get('a')
lru.put('c', 3)
print(list(lru.cache.items()))
实际应用: 插件系统、缓存、ORM、数据结构等都大量用到OOP进阶特性。

6. 常见错误与调试

# MRO调试
print(Dog.__mro__)
# __repr__调试
class Demo:
    def __repr__(self):
        return ''
print(Demo())

7. 编程练习与挑战

练习1:基础操作

练习2:进阶技巧

练习3:实战项目

8. 综合作业与项目

作业21:类的进阶综合应用

任务1:多态与插件系统

实现一个插件系统,支持注册多种插件类,统一调用接口,动态扩展功能。

任务2:自定义容器与数据结构

实现一个自定义容器类,支持下标、切片、for循环、只读、缓存等特性,并与内置list对比。

任务3:OOP设计模式实践

实现工厂、单例、装饰器等常见OOP设计模式的Python代码示例。

任务4(可选扩展):

用UML类图工具画出你的类结构,并分析其高内聚、低耦合特性。

学习建议:OOP进阶特性是写好大型项目的关键,建议多动手实践,理解继承、多态、魔法方法、容器协议、抽象基类、设计模式等高级用法,遇到报错要学会调试和查文档。推荐多用MRO、__repr__、UML等工具辅助调试和设计。
思考题:多态和鸭子类型的区别?自定义容器类有哪些协议?如何设计一个可扩展的插件系统?OOP设计模式在实际开发中的作用?组合和继承如何选择?UML类图在设计中的作用?