Python面向对象的多态特性详解

文章目录

    • 一、什么是多态?
      • [1.1 多态的核心思想](#1.1 多态的核心思想)
      • [1.2 多态的类型](#1.2 多态的类型)
    • 二、继承式多态
      • [2.1 基本实现](#2.1 基本实现)
      • [2.2 抽象基类实现多态](#2.2 抽象基类实现多态)
    • 三、鸭子类型多态
      • [3.1 鸭子类型原理](#3.1 鸭子类型原理)
      • [3.2 鸭子类型的高级应用](#3.2 鸭子类型的高级应用)
    • 四、运算符多态
      • [4.1 算术运算符多态](#4.1 算术运算符多态)
      • [4.2 比较运算符多态](#4.2 比较运算符多态)
    • 五、函数和内置函数的多态
      • [5.1 len()函数的多态](#5.1 len()函数的多态)
      • [5.2 内置函数的多态](#5.2 内置函数的多态)
    • 六、多态的实际应用场景
      • [6.1 插件系统](#6.1 插件系统)
      • [6.2 策略模式](#6.2 策略模式)
      • [6.3 日志系统](#6.3 日志系统)
    • 七、多态的优缺点和最佳实践
      • [7.1 多态的优缺点对比](#7.1 多态的优缺点对比)
      • [7.2 多态最佳实践](#7.2 多态最佳实践)
    • 八、总结
      • [8.1 多态的核心要点](#8.1 多态的核心要点)
      • [8.2 多态与其他特性的关系](#8.2 多态与其他特性的关系)

一、什么是多态?

多态(Polymorphism)是面向对象编程的三大特性之一(继承、封装、多态)。多态字面意思就是"多种形态",指同一个接口可以有不同的实现方式,或者同一个操作可以作用于不同的对象并产生不同的行为。

1.1 多态的核心思想

  • 同一接口,不同实现:同样的方法名在不同类中有不同的实现
  • 动态绑定:程序运行时才决定调用哪个方法
  • 可替换性:子类对象可以替换父类对象使用
  • 扩展性:新增功能不需要修改原有代码

1.2 多态的类型

Python支持两种多态:

  • 继承式多态:通过继承和重写实现
  • 鸭子类型多态:通过动态类型系统实现

二、继承式多态

2.1 基本实现

python 复制代码
# 基类(父类)
class Animal:
    """动物基类"""
    
    def __init__(self, name):
        self.name = name
    
    def make_sound(self):
        """发出声音(基类方法)"""
        return "动物发出声音"
    
    def move(self):
        """移动方式(基类方法)"""
        return "动物移动"

# 子类1
class Dog(Animal):
    """狗类"""
    
    def make_sound(self):
        """重写父类方法"""
        return f"{self.name}:汪汪汪!"
    
    def move(self):
        return f"{self.name}:四条腿奔跑"

# 子类2
class Cat(Animal):
    """猫类"""
    
    def make_sound(self):
        return f"{self.name}:喵喵喵~"
    
    def move(self):
        return f"{self.name}:悄无声息地走路"

# 子类3
class Bird(Animal):
    """鸟类"""
    
    def make_sound(self):
        return f"{self.name}:啾啾啾!"
    
    def move(self):
        return f"{self.name}:展翅飞翔"

# 多态函数
def animal_behavior(animal):
    """
    演示多态:同一个函数可以处理不同类型的动物
    """
    print(animal.make_sound())
    print(animal.move())
    print("-" * 30)

# 使用示例
if __name__ == "__main__":
    # 创建不同类型的动物对象
    animals = [
        Dog("旺财"),
        Cat("咪咪"),
        Bird("小鸟")
    ]
    
    # 统一调用,展现不同行为
    for animal in animals:
        animal_behavior(animal)

多态调用流程图:
Dog类型
Cat类型
Bird类型
其他类型
调用animal_behavior函数
传入animal对象
animal是什么类型?
调用Dog.make_sound
调用Cat.make_sound
调用Bird.make_sound
调用Animal.make_sound
返回不同结果

2.2 抽象基类实现多态

python 复制代码
from abc import ABC, abstractmethod
import math

class Shape(ABC):
    """形状抽象基类"""
    
    @abstractmethod
    def area(self):
        """计算面积(抽象方法)"""
        pass
    
    @abstractmethod
    def perimeter(self):
        """计算周长(抽象方法)"""
        pass
    
    def description(self):
        """具体方法(所有子类共享)"""
        return f"这是一个{self.__class__.__name__},面积:{self.area():.2f},周长:{self.perimeter():.2f}"

class Circle(Shape):
    """圆形"""
    
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return math.pi * self.radius ** 2
    
    def perimeter(self):
        return 2 * math.pi * self.radius

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 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
        return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
    
    def perimeter(self):
        return self.a + self.b + self.c

# 多态函数
def print_shape_info(shapes):
    """打印多个形状的信息"""
    for shape in shapes:
        print(shape.description())

# 使用示例
shapes = [
    Circle(5),
    Rectangle(4, 6),
    Triangle(3, 4, 5)
]

print_shape_info(shapes)

三、鸭子类型多态

3.1 鸭子类型原理

"当看到一只鸟走起来像鸭子、游泳像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"

python 复制代码
class Duck:
    """鸭子类"""
    
    def quack(self):
        return "鸭子嘎嘎叫"
    
    def swim(self):
        return "鸭子游泳"

class Person:
    """人类"""
    
    def quack(self):
        return "人类模仿鸭子叫"
    
    def swim(self):
        return "人类游泳"

class Robot:
    """机器人"""
    
    def quack(self):
        return "机器人发出嘎嘎声"
    
    def swim(self):
        return "机器人防水游泳"

# 鸭子类型函数:不关心对象类型,只关心是否有相应方法
def make_it_quack(thing):
    """让任何有quack方法的对象叫"""
    print(thing.quack())

def make_it_swim(thing):
    """让任何有swim方法的对象游泳"""
    print(thing.swim())

# 使用示例
objects = [Duck(), Person(), Robot()]

for obj in objects:
    make_it_quack(obj)
    make_it_swim(obj)
    print("-" * 30)

鸭子类型流程图:




传入对象
是否有quack方法?
调用quack方法
抛出AttributeError
是否有swim方法?
调用swim方法
抛出AttributeError
Duck对象
Person对象
Robot对象

3.2 鸭子类型的高级应用

python 复制代码
class MusicPlayer:
    """音乐播放器"""
    
    def play(self, song):
        return f"播放音乐:{song}"
    
    def stop(self):
        return "停止播放音乐"

class VideoPlayer:
    """视频播放器"""
    
    def play(self, video):
        return f"播放视频:{video}"
    
    def stop(self):
        return "停止播放视频"
    
    def subtitle(self):
        return "显示字幕"

class GameConsole:
    """游戏机"""
    
    def play(self, game):
        return f"运行游戏:{game}"
    
    def stop(self):
        return "退出游戏"
    
    def save_progress(self):
        return "保存游戏进度"

class MediaController:
    """媒体控制器(使用鸭子类型)"""
    
    def __init__(self):
        self.current_device = None
    
    def connect(self, device):
        """连接任何有play和stop方法的设备"""
        if hasattr(device, 'play') and hasattr(device, 'stop'):
            self.current_device = device
            return f"已连接到{device.__class__.__name__}"
        else:
            raise TypeError("设备必须实现play和stop方法")
    
    def play(self, content):
        """播放内容"""
        if self.current_device:
            return self.current_device.play(content)
        return "没有连接设备"
    
    def stop(self):
        """停止"""
        if self.current_device:
            return self.current_device.stop()
        return "没有连接设备"

# 使用示例
controller = MediaController()

# 连接不同类型的设备
devices = [MusicPlayer(), VideoPlayer(), GameConsole()]

for device in devices:
    print(controller.connect(device))
    print(controller.play("测试内容"))
    print(controller.stop())
    
    # 特定设备特有的方法
    if hasattr(device, 'subtitle'):
        print(device.subtitle())
    if hasattr(device, 'save_progress'):
        print(device.save_progress())
    print("-" * 30)

四、运算符多态

Python中的运算符实际上是通过特殊方法实现的多态。

4.1 算术运算符多态

python 复制代码
class Vector2D:
    """二维向量类"""
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        """重载加法运算符"""
        if isinstance(other, Vector2D):
            return Vector2D(self.x + other.x, self.y + other.y)
        elif isinstance(other, (int, float)):
            return Vector2D(self.x + other, self.y + other)
        else:
            raise TypeError(f"不支持Vector2D和{type(other)}的加法")
    
    def __sub__(self, other):
        """重载减法运算符"""
        if isinstance(other, Vector2D):
            return Vector2D(self.x - other.x, self.y - other.y)
        elif isinstance(other, (int, float)):
            return Vector2D(self.x - other, self.y - other)
        else:
            raise TypeError(f"不支持Vector2D和{type(other)}的减法")
    
    def __mul__(self, scalar):
        """重载乘法运算符"""
        if isinstance(scalar, (int, float)):
            return Vector2D(self.x * scalar, self.y * scalar)
        raise TypeError(f"不支持Vector2D和{type(scalar)}的乘法")
    
    def __rmul__(self, scalar):
        """右乘法(处理 scalar * vector)"""
        return self.__mul__(scalar)
    
    def __abs__(self):
        """重载绝对值运算符"""
        return (self.x ** 2 + self.y ** 2) ** 0.5
    
    def __str__(self):
        return f"Vector2D({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Vector2D({self.x}, {self.y})"

class ComplexNumber:
    """复数类"""
    
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
    
    def __add__(self, other):
        """复数加法"""
        if isinstance(other, ComplexNumber):
            return ComplexNumber(self.real + other.real, self.imag + other.imag)
        elif isinstance(other, (int, float)):
            return ComplexNumber(self.real + other, self.imag)
        else:
            raise TypeError(f"不支持ComplexNumber和{type(other)}的加法")
    
    def __mul__(self, other):
        """复数乘法"""
        if isinstance(other, ComplexNumber):
            real = self.real * other.real - self.imag * other.imag
            imag = self.real * other.imag + self.imag * other.real
            return ComplexNumber(real, imag)
        elif isinstance(other, (int, float)):
            return ComplexNumber(self.real * other, self.imag * other)
        else:
            raise TypeError(f"不支持ComplexNumber和{type(other)}的乘法")
    
    def __abs__(self):
        """复数的模"""
        return (self.real ** 2 + self.imag ** 2) ** 0.5
    
    def __str__(self):
        sign = '+' if self.imag >= 0 else '-'
        return f"{self.real} {sign} {abs(self.imag)}i"

# 多态演示
print("=== 运算符多态演示 ===")
v1 = Vector2D(3, 4)
v2 = Vector2D(1, 2)

print(f"v1 + v2 = {v1 + v2}")
print(f"v1 - v2 = {v1 - v2}")
print(f"v1 * 3 = {v1 * 3}")
print(f"2 * v1 = {2 * v1}")
print(f"|v1| = {abs(v1)}")

print("\n=== 复数运算 ===")
c1 = ComplexNumber(3, 4)
c2 = ComplexNumber(1, -2)
print(f"c1 + c2 = {c1 + c2}")
print(f"c1 * c2 = {c1 * c2}")
print(f"|c1| = {abs(c1)}")

4.2 比较运算符多态

python 复制代码
class Person:
    """人员类"""
    
    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.salary = salary
    
    def __lt__(self, other):
        """小于比较(按年龄)"""
        if isinstance(other, Person):
            return self.age < other.age
        return NotImplemented
    
    def __le__(self, other):
        """小于等于"""
        if isinstance(other, Person):
            return self.age <= other.age
        return NotImplemented
    
    def __gt__(self, other):
        """大于比较"""
        if isinstance(other, Person):
            return self.age > other.age
        return NotImplemented
    
    def __ge__(self, other):
        """大于等于"""
        if isinstance(other, Person):
            return self.age >= other.age
        return NotImplemented
    
    def __eq__(self, other):
        """等于比较"""
        if isinstance(other, Person):
            return self.age == other.age and self.name == other.name
        return False
    
    def __ne__(self, other):
        """不等于"""
        return not self.__eq__(other)
    
    def __str__(self):
        return f"{self.name}({self.age}岁)"

# 创建人员列表
people = [
    Person("张三", 25, 8000),
    Person("李四", 30, 10000),
    Person("王五", 22, 6000),
    Person("赵六", 28, 9000)
]

# 多态排序(使用自定义的比较运算符)
print("按年龄排序:")
sorted_people = sorted(people)
for person in sorted_people:
    print(person)

# 多态比较
print(f"\n张三是否小于李四? {people[0] < people[1]}")
print(f"王五是否大于赵六? {people[2] > people[3]}")
print(f"张三是否等于自己? {people[0] == Person('张三', 25, 8000)}")

五、函数和内置函数的多态

5.1 len()函数的多态

python 复制代码
class CustomList:
    """自定义列表类"""
    
    def __init__(self, items):
        self.items = items
    
    def __len__(self):
        """实现__len__方法使对象支持len()函数"""
        return len(self.items)
    
    def __getitem__(self, index):
        return self.items[index]

class MultiLevelList:
    """多层列表"""
    
    def __init__(self, *layers):
        self.layers = layers
    
    def __len__(self):
        """返回总元素个数"""
        total = 0
        for layer in self.layers:
            total += len(layer)
        return total

# len()函数可以作用于不同类型的对象
print("=== len()函数的多态 ===")
print(f"字符串长度:{len('Hello')}")
print(f"列表长度:{len([1, 2, 3, 4])}")
print(f"字典长度:{len({'a':1, 'b':2})}")
print(f"自定义列表长度:{len(CustomList([1,2,3,4,5]))}")
print(f"多层列表长度:{len(MultiLevelList([1,2], [3,4,5], [6,7,8,9]))}")

5.2 内置函数的多态

python 复制代码
class DataAnalyzer:
    """数据分析器"""
    
    def __init__(self, data):
        self.data = data
    
    def __iter__(self):
        """使对象可迭代"""
        return iter(self.data)
    
    def __contains__(self, item):
        """使对象支持in操作符"""
        return item in self.data
    
    def __reversed__(self):
        """使对象支持reversed()函数"""
        return reversed(self.data)
    
    def __str__(self):
        return f"DataAnalyzer({self.data})"

class RangeSequence:
    """范围序列"""
    
    def __init__(self, start, end, step=1):
        self.start = start
        self.end = end
        self.step = step
        self._data = list(range(start, end, step))
    
    def __iter__(self):
        return iter(self._data)
    
    def __len__(self):
        return len(self._data)
    
    def __getitem__(self, index):
        return self._data[index]
    
    def __contains__(self, item):
        """优化包含检查"""
        if not isinstance(item, (int, float)):
            return False
        return (self.start <= item < self.end and 
                (item - self.start) % self.step == 0)

# 演示各种内置函数的多态行为
print("=== 内置函数多态演示 ===")

# 创建对象
analyzer = DataAnalyzer([10, 20, 30, 40, 50])
sequence = RangeSequence(1, 10, 2)

# iter()函数
print("iter()函数:")
for item in analyzer:
    print(f"  {item}")
print()

# in运算符
print("in运算符:")
print(f"30 in analyzer? {30 in analyzer}")
print(f"5 in sequence? {5 in sequence}")
print(f"6 in sequence? {6 in sequence}")
print()

# reversed()函数
print("reversed()函数:")
for item in reversed(analyzer):
    print(f"  {item}")
print()

# max()和min()函数
print(f"max(analyzer) = {max(analyzer)}")
print(f"min(sequence) = {min(sequence)}")
print(f"sum(sequence) = {sum(sequence)}")

六、多态的实际应用场景

6.1 插件系统

python 复制代码
from abc import ABC, abstractmethod
import json
import csv

class DataExporter(ABC):
    """数据导出器基类"""
    
    @abstractmethod
    def export(self, data, filename):
        """导出数据"""
        pass
    
    @abstractmethod
    def get_extension(self):
        """获取文件扩展名"""
        pass

class JSONExporter(DataExporter):
    """JSON导出器"""
    
    def export(self, data, filename):
        full_name = f"{filename}.{self.get_extension()}"
        with open(full_name, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        return f"数据已导出到 {full_name}"
    
    def get_extension(self):
        return "json"

class CSVExporter(DataExporter):
    """CSV导出器"""
    
    def export(self, data, filename):
        full_name = f"{filename}.{self.get_extension()}"
        with open(full_name, 'w', newline='', encoding='utf-8') as f:
            if data and isinstance(data, list):
                writer = csv.DictWriter(f, fieldnames=data[0].keys())
                writer.writeheader()
                writer.writerows(data)
        return f"数据已导出到 {full_name}"
    
    def get_extension(self):
        return "csv"

class XMLExporter(DataExporter):
    """XML导出器"""
    
    def export(self, data, filename):
        full_name = f"{filename}.{self.get_extension()}"
        with open(full_name, 'w', encoding='utf-8') as f:
            f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
            f.write('<data>\n')
            for item in data:
                f.write('  <item>\n')
                for key, value in item.items():
                    f.write(f'    <{key}>{value}</{key}>\n')
                f.write('  </item>\n')
            f.write('</data>')
        return f"数据已导出到 {full_name}"
    
    def get_extension(self):
        return "xml"

class ExportManager:
    """导出管理器(使用多态)"""
    
    def __init__(self):
        self.exporters = {}
    
    def register_exporter(self, name, exporter):
        """注册导出器"""
        if isinstance(exporter, DataExporter):
            self.exporters[name] = exporter
            return f"已注册导出器:{name}"
        raise TypeError("必须继承DataExporter类")
    
    def export_data(self, data, filename, format_type):
        """导出数据"""
        if format_type not in self.exporters:
            available = ', '.join(self.exporters.keys())
            return f"不支持的格式:{format_type},可用格式:{available}"
        
        exporter = self.exporters[format_type]
        return exporter.export(data, filename)

# 使用示例
data = [
    {"name": "张三", "age": 25, "city": "北京"},
    {"name": "李四", "age": 30, "city": "上海"},
    {"name": "王五", "age": 28, "city": "广州"}
]

# 创建导出管理器
manager = ExportManager()

# 注册各种导出器
manager.register_exporter("json", JSONExporter())
manager.register_exporter("csv", CSVExporter())
manager.register_exporter("xml", XMLExporter())

# 多态调用
print(manager.export_data(data, "users", "json"))
print(manager.export_data(data, "users", "csv"))
print(manager.export_data(data, "users", "xml"))

6.2 策略模式

python 复制代码
from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    """支付策略基类"""
    
    @abstractmethod
    def pay(self, amount):
        """支付方法"""
        pass
    
    @abstractmethod
    def get_name(self):
        """获取支付方式名称"""
        pass

class CreditCardPayment(PaymentStrategy):
    """信用卡支付"""
    
    def __init__(self, card_number, cvv, expiry):
        self.card_number = card_number[-4:]
        self.cvv = cvv
        self.expiry = expiry
    
    def pay(self, amount):
        # 信用卡支付逻辑
        return f"使用信用卡({self.card_number})支付 {amount} 元成功"
    
    def get_name(self):
        return "信用卡支付"

class AlipayPayment(PaymentStrategy):
    """支付宝支付"""
    
    def __init__(self, account):
        self.account = account
    
    def pay(self, amount):
        # 支付宝支付逻辑
        return f"使用支付宝账户({self.account})支付 {amount} 元成功"
    
    def get_name(self):
        return "支付宝支付"

class WechatPayment(PaymentStrategy):
    """微信支付"""
    
    def __init__(self, open_id):
        self.open_id = open_id
    
    def pay(self, amount):
        # 微信支付逻辑
        return f"使用微信(open_id:{self.open_id[:8]}...)支付 {amount} 元成功"
    
    def get_name(self):
        return "微信支付"

class CashPayment(PaymentStrategy):
    """现金支付"""
    
    def pay(self, amount):
        return f"使用现金支付 {amount} 元,找零请自理"
    
    def get_name(self):
        return "现金支付"

class ShoppingCart:
    """购物车"""
    
    def __init__(self):
        self.items = []
        self.total = 0
    
    def add_item(self, name, price, quantity=1):
        self.items.append({
            'name': name,
            'price': price,
            'quantity': quantity,
            'subtotal': price * quantity
        })
        self.total += price * quantity
    
    def checkout(self, payment_strategy):
        """结账(使用多态)"""
        if not payment_strategy:
            return "请选择支付方式"
        
        if not self.items:
            return "购物车是空的"
        
        print("\n=== 购物清单 ===")
        for item in self.items:
            print(f"{item['name']} x{item['quantity']} = {item['subtotal']}元")
        print(f"总计:{self.total}元")
        print(f"支付方式:{payment_strategy.get_name()}")
        
        return payment_strategy.pay(self.total)

# 使用示例
cart = ShoppingCart()
cart.add_item("Python编程", 89, 2)
cart.add_item("机械键盘", 399, 1)
cart.add_item("鼠标", 129, 1)

# 使用不同的支付方式
print(cart.checkout(CreditCardPayment("1234567890123456", "123", "12/25")))
print()
print(cart.checkout(AlipayPayment("user@example.com")))
print()
print(cart.checkout(WechatPayment("wx_open_id_123456789")))
print()
print(cart.checkout(CashPayment()))

6.3 日志系统

python 复制代码
from abc import ABC, abstractmethod
from datetime import datetime
import os

class LogHandler(ABC):
    """日志处理器基类"""
    
    @abstractmethod
    def handle(self, message, level):
        """处理日志"""
        pass
    
    @abstractmethod
    def get_level_name(self, level):
        """获取级别名称"""
        pass

class ConsoleLogHandler(LogHandler):
    """控制台日志处理器"""
    
    def __init__(self, show_time=True):
        self.show_time = show_time
    
    def handle(self, message, level):
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') if self.show_time else ''
        level_name = self.get_level_name(level)
        
        if level >= 40:  # ERROR级别用红色
            color = '\033[91m'
        elif level >= 30:  # WARNING级别用黄色
            color = '\033[93m'
        elif level >= 20:  # INFO级别用绿色
            color = '\033[92m'
        else:  # DEBUG级别用蓝色
            color = '\033[94m'
        
        reset = '\033[0m'
        
        log_line = f"{color}[{level_name}]{reset} {timestamp} - {message}"
        print(log_line)
    
    def get_level_name(self, level):
        levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
        return levels.get(level, 'UNKNOWN')

class FileLogHandler(LogHandler):
    """文件日志处理器"""
    
    def __init__(self, filename='app.log', max_size=1024*1024):
        self.filename = filename
        self.max_size = max_size
        self._check_rotation()
    
    def _check_rotation(self):
        """检查是否需要轮转日志文件"""
        if os.path.exists(self.filename):
            size = os.path.getsize(self.filename)
            if size > self.max_size:
                # 简单的日志轮转
                base, ext = os.path.splitext(self.filename)
                for i in range(9, 0, -1):
                    old = f"{base}.{i}{ext}"
                    new = f"{base}.{i+1}{ext}" if i < 9 else f"{base}.{i+1}{ext}"
                    if os.path.exists(old):
                        os.rename(old, new)
                os.rename(self.filename, f"{base}.1{ext}")
    
    def handle(self, message, level):
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        level_name = self.get_level_name(level)
        
        log_line = f"[{level_name}] {timestamp} - {message}\n"
        
        with open(self.filename, 'a', encoding='utf-8') as f:
            f.write(log_line)
    
    def get_level_name(self, level):
        levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
        return levels.get(level, 'UNKNOWN')

class DatabaseLogHandler(LogHandler):
    """数据库日志处理器"""
    
    def __init__(self, connection_string):
        self.connection_string = connection_string
        self.logs = []  # 模拟数据库
    
    def handle(self, message, level):
        timestamp = datetime.now()
        level_name = self.get_level_name(level)
        
        log_entry = {
            'timestamp': timestamp,
            'level': level,
            'level_name': level_name,
            'message': message
        }
        
        self.logs.append(log_entry)
        
        # 模拟数据库写入
        print(f"[数据库日志] 已写入 {len(self.logs)} 条记录")
    
    def get_level_name(self, level):
        levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
        return levels.get(level, 'UNKNOWN')
    
    def query_logs(self, level=None, limit=10):
        """查询日志"""
        results = self.logs
        if level:
            results = [log for log in results if log['level'] == level]
        return results[-limit:]

class Logger:
    """日志器(使用多态)"""
    
    def __init__(self, name):
        self.name = name
        self.handlers = []
    
    def add_handler(self, handler):
        if isinstance(handler, LogHandler):
            self.handlers.append(handler)
    
    def log(self, level, message):
        for handler in self.handlers:
            handler.handle(f"[{self.name}] {message}", level)
    
    def debug(self, message):
        self.log(10, message)
    
    def info(self, message):
        self.log(20, message)
    
    def warning(self, message):
        self.log(30, message)
    
    def error(self, message):
        self.log(40, message)
    
    def critical(self, message):
        self.log(50, message)

# 使用示例
logger = Logger("MyApp")

# 添加多个处理器
logger.add_handler(ConsoleLogHandler())
logger.add_handler(FileLogHandler("myapp.log"))
logger.add_handler(DatabaseLogHandler("mysql://localhost/logs"))

# 记录日志
logger.debug("这是调试信息")
logger.info("用户登录成功")
logger.warning("磁盘空间不足")
logger.error("数据库连接失败")
logger.critical("系统崩溃")

# 查询数据库日志
db_handler = logger.handlers[2]  # 获取数据库处理器
print("\n最近5条数据库日志:")
for log in db_handler.query_logs(limit=5):
    print(f"  {log['level_name']}: {log['message']}")

七、多态的优缺点和最佳实践

7.1 多态的优缺点对比

python 复制代码
class PolymorphismDemo:
    """
    多态优缺点演示
    """
    
    # 优点:扩展性
    def demonstrate_extensibility(self):
        """演示多态的扩展性"""
        class Animal:
            def speak(self):
                return "动物叫"
        
        class Dog(Animal):
            def speak(self):
                return "汪汪汪"
        
        class Cat(Animal):
            def speak(self):
                return "喵喵喵"
        
        # 新增一个动物类,不需要修改原有代码
        class Duck(Animal):
            def speak(self):
                return "嘎嘎嘎"
        
        animals = [Dog(), Cat(), Duck()]
        for animal in animals:
            print(animal.speak())
    
    # 优点:可维护性
    def demonstrate_maintainability(self):
        """演示多态的可维护性"""
        class Shape:
            def area(self):
                pass
        
        class Circle(Shape):
            def __init__(self, r):
                self.r = r
            def area(self):
                return 3.14 * self.r ** 2
        
        class Rectangle(Shape):
            def __init__(self, w, h):
                self.w = w
                self.h = h
            def area(self):
                return self.w * self.h
        
        # 修改面积计算方式时,只需要修改对应类
        # 调用代码完全不需要修改
        shapes = [Circle(5), Rectangle(4, 6)]
        for shape in shapes:
            print(f"面积:{shape.area()}")
    
    # 缺点:性能开销
    def demonstrate_overhead(self):
        """演示多态的性能开销"""
        import time
        
        # 使用多态
        class Processor:
            def process(self, data):
                return data * 2
        
        class FastProcessor(Processor):
            def process(self, data):
                return data * 2
        
        # 直接调用
        start = time.time()
        p = Processor()
        for i in range(1000000):
            result = p.process(i)
        direct_time = time.time() - start
        
        # 多态调用
        start = time.time()
        p = FastProcessor()
        for i in range(1000000):
            result = p.process(i)
        polymorphic_time = time.time() - start
        
        print(f"直接调用时间:{direct_time:.4f}秒")
        print(f"多态调用时间:{polymorphic_time:.4f}秒")
        print(f"性能差异:{(polymorphic_time/direct_time-1)*100:.2f}%")
    
    # 缺点:调试复杂性
    def demonstrate_complexity(self):
        """演示多态的调试复杂性"""
        class Base:
            def method(self):
                return "Base"
        
        class A(Base):
            def method(self):
                return "A"
        
        class B(Base):
            def method(self):
                return "B"
        
        class C(A, B):  # 多重继承
            pass
        
        obj = C()
        # 需要追踪方法解析顺序
        print(f"方法解析顺序:{C.__mro__}")
        print(f"调用结果:{obj.method()}")

# 使用示例
demo = PolymorphismDemo()
print("=== 扩展性演示 ===")
demo.demonstrate_extensibility()
print("\n=== 可维护性演示 ===")
demo.demonstrate_maintainability()
print("\n=== 性能开销演示 ===")
demo.demonstrate_overhead()
print("\n=== 调试复杂性演示 ===")
demo.demonstrate_complexity()

7.2 多态最佳实践

python 复制代码
from abc import ABC, abstractmethod
from typing import List, Union

class DataProcessor(ABC):
    """
    数据处理器基类(最佳实践示例)
    """
    
    def __init__(self, name: str):
        self.name = name
        self._processed_count = 0
    
    @abstractmethod
    def process(self, data):
        """处理数据(抽象方法)"""
        pass
    
    def get_stats(self) -> dict:
        """获取统计信息(具体方法)"""
        return {
            'processor_name': self.name,
            'processed_count': self._processed_count,
            'processor_type': self.__class__.__name__
        }
    
    def _increment_count(self):
        """增加处理计数(保护方法)"""
        self._processed_count += 1

class TextProcessor(DataProcessor):
    """文本处理器"""
    
    def __init__(self, name="文本处理器"):
        super().__init__(name)
        self.encoding = 'utf-8'
    
    def process(self, data):
        if not isinstance(data, str):
            data = str(data)
        
        # 文本处理逻辑
        result = data.upper()
        self._increment_count()
        return result

class NumberProcessor(DataProcessor):
    """数字处理器"""
    
    def __init__(self, name="数字处理器", multiplier=2):
        super().__init__(name)
        self.multiplier = multiplier
    
    def process(self, data):
        if not isinstance(data, (int, float)):
            try:
                data = float(data)
            except (ValueError, TypeError):
                return 0
        
        result = data * self.multiplier
        self._increment_count()
        return result

class ListProcessor(DataProcessor):
    """列表处理器"""
    
    def __init__(self, name="列表处理器"):
        super().__init__(name)
        self.max_items = 100
    
    def process(self, data):
        if not isinstance(data, (list, tuple)):
            if hasattr(data, '__iter__'):
                data = list(data)
            else:
                data = [data]
        
        # 限制列表长度
        result = data[:self.max_items]
        self._increment_count()
        return result

class ProcessingPipeline:
    """
    处理管道(多态组合)
    """
    
    def __init__(self):
        self.processors: List[DataProcessor] = []
    
    def add_processor(self, processor: DataProcessor):
        """添加处理器"""
        if isinstance(processor, DataProcessor):
            self.processors.append(processor)
            return True
        return False
    
    def process_data(self, data):
        """处理数据"""
        current_data = data
        for processor in self.processors:
            try:
                current_data = processor.process(current_data)
                print(f"  [{processor.name}] 处理完成")
            except Exception as e:
                print(f"  [{processor.name}] 处理失败:{e}")
                break
        return current_data
    
    def get_pipeline_stats(self):
        """获取管道统计信息"""
        return [proc.get_stats() for proc in self.processors]

# 使用示例
pipeline = ProcessingPipeline()

# 添加不同类型的处理器
pipeline.add_processor(TextProcessor())
pipeline.add_processor(NumberProcessor(multiplier=3))
pipeline.add_processor(ListProcessor())

# 处理不同类型的数据
test_data = [
    "hello world",
    42,
    [1, 2, 3, 4, 5],
    {"key": "value"}
]

print("=== 处理管道演示 ===")
for data in test_data:
    print(f"\n处理数据:{data}")
    result = pipeline.process_data(data)
    print(f"最终结果:{result}")

print("\n=== 管道统计信息 ===")
for stats in pipeline.get_pipeline_stats():
    print(stats)

八、总结

8.1 多态的核心要点

python 复制代码
class PolymorphismSummary:
    """
    多态总结类
    """
    
    @staticmethod
    def summary():
        """多态总结"""
        print("""
        ========== Python多态特性总结 ==========
        
        1. 多态的定义
           - 同一个接口,不同的实现
           - 同一个操作作用于不同对象产生不同结果
        
        2. 多态的实现方式
           - 继承式多态:通过继承和方法重写
           - 鸭子类型:只要有相应方法就可以
           - 运算符多态:通过特殊方法实现
        
        3. 多态的优点
           - 可扩展性:易于添加新功能
           - 可维护性:修改不影响调用方
           - 可复用性:代码复用程度高
           - 灵活性:动态绑定,运行时决定
        
        4. 多态的注意事项
           - 性能开销:动态查找有一定成本
           - 调试难度:需要理解继承链
           - 设计复杂度:需要合理设计类结构
        
        5. 最佳实践
           - 使用抽象基类定义接口
           - 遵循里氏替换原则
           - 优先考虑组合而非继承
           - 合理使用鸭子类型
           - 做好异常处理
        
        6. 适用场景
           - 插件系统
           - 策略模式
           - 工厂模式
           - 框架设计
           - API设计
        """)

# 调用总结
PolymorphismSummary.summary()

8.2 多态与其他特性的关系

python 复制代码
class RelationshipDemo:
    """
    多态与封装、继承的关系
    """
    
    class Animal:
        """动物基类"""
        
        def __init__(self, name):
            self.__name = name  # 封装:私有属性
        
        @property
        def name(self):  # 封装:属性访问器
            return self.__name
        
        def speak(self):  # 多态:待重写的方法
            raise NotImplementedError("子类必须实现speak方法")
        
        def __str__(self):  # 封装:字符串表示
            return f"{self.__class__.__name__}({self.__name})"
    
    class Dog(Animal):  # 继承
        def speak(self):  # 多态:重写方法
            return f"{self.name} 汪汪汪"
    
    class Cat(Animal):  # 继承
        def speak(self):  # 多态:重写方法
            return f"{self.name} 喵喵喵"
    
    @classmethod
    def demonstrate(cls):
        """演示三者关系"""
        animals = [
            cls.Dog("旺财"),
            cls.Cat("咪咪")
        ]
        
        for animal in animals:
            # 多态调用
            print(animal.speak())
            # 封装调用
            print(f"  名称:{animal.name}")
            print(f"  类型:{type(animal)}")
            print(f"  字符串:{animal}")
            print()

# 使用示例
RelationshipDemo.demonstrate()

通过以上详细的讲解和丰富的示例,我们可以看到Python的多态特性提供了强大的灵活性和扩展性。多态使得代码更加模块化、易于维护和扩展,是面向对象编程中不可或缺的重要特性。合理使用多态可以让我们的代码更加优雅、灵活和强大。

相关推荐
秋刀奈1 小时前
Python 现代工程实践
python
清水白石0081 小时前
Fixture 的力量:pytest fixture 如何重新定义测试数据管理
数据库·python·pytest
yngsqq1 小时前
多段线顶点遍历技巧(适用闭合和非闭合)
开发语言
宇木灵2 小时前
C语言基础-五、数组
c语言·开发语言·学习·算法
lanbo_ai2 小时前
基于yolov10的火焰、火灾检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
pytorch·python·yolo
databook2 小时前
🚀 Manim CE v0.20.0 发布:动画构建更丝滑,随机性终于“可控”了!
python·动效
何中应2 小时前
使用Python统计小说语言描写的字数
后端·python
xyq20242 小时前
空对象模式
开发语言