Python 面向对象编程:抽象类、接口与继承系统教程

第一部分:面向对象编程基础概念

1.1 为什么需要面向对象编程?

传统编程 vs 面向对象编程

PYTHON 复制代码
# 传统过程式编程
student1_name = "张三"
student1_age = 20
student1_score = 85


student2_name = "李四"
student2_age = 21
student2_score = 90


def calculate_grade(student_score):
    if student_score >= 90:
        return "A"
    elif student_score >= 80:
        return "B"
    else:
        return "C"


# 问题:数据和函数分离,难以管理
PYTHON 复制代码
# 面向对象编程
class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
    
    def calculate_grade(self):
        if self.score >= 90:
            return "A"
        elif self.score >= 80:
            return "B"
        else:
            return "C"


# 创建对象
student1 = Student("张三", 20, 85)
student2 = Student("李四", 21, 90)


# 统一处理
print(student1.calculate_grade())  # B
print(student2.calculate_grade())  # A

1.2 三大核心特征

1.2.1 封装(Encapsulation)

PYTHON 复制代码
class BankAccount:
    def __init__(self, account_number, owner, balance=0):
        self._account_number = account_number  # 受保护属性
        self.owner = owner                     # 公开属性
        self.__balance = balance               # 私有属性(双下划线)
        self.__transaction_history = []        # 私有属性
    
    def deposit(self, amount):
        """存款"""
        if amount > 0:
            self.__balance += amount
            self.__add_transaction(f"存款: +{amount}")
            return True
        return False
    
    def withdraw(self, amount):
        """取款"""
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            self.__add_transaction(f"取款: -{amount}")
            return True
        return False
    
    def get_balance(self):
        """获取余额(通过方法访问私有属性)"""
        return self.__balance
    
    def __add_transaction(self, record):
        """私有方法:添加交易记录"""
        self.__transaction_history.append(record)
    
    def get_transaction_history(self):
        """获取交易历史"""
        return self.__transaction_history.copy()  # 返回副本,保护数据


# 使用
account = BankAccount("123456", "张三", 1000)
account.deposit(500)
account.withdraw(200)
print(f"余额: {account.get_balance()}")  # 1300
print(f"交易记录: {account.get_transaction_history()}")


# 无法直接访问私有属性
# print(account.__balance)  # 错误!AttributeError
# print(account._BankAccount__balance)  # 可以访问,但不推荐

1.2.2 继承(Inheritance)

PYTHON 复制代码
# 父类(基类)
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}正在睡觉...")
    
    def make_sound(self):
        print(f"{self.name}发出声音...")


# 子类(派生类)
class Dog(Animal):  # 继承Animal类
    def __init__(self, name, age, breed):
        super().__init__(name, age)  # 调用父类初始化方法
        self.breed = breed  # 子类特有属性
        
    # 方法重写(方法覆盖)
    def make_sound(self):
        print(f"{self.name}汪汪叫!")
    
    # 子类特有方法
    def fetch(self):
        print(f"{self.name}正在捡球...")


class Cat(Animal):
    def __init__(self, name, age, color):
        super().__init__(name, age)
        self.color = color
    
    def make_sound(self):
        print(f"{self.name}喵喵叫!")
    
    def climb_tree(self):
        print(f"{self.name}正在爬树...")


# 使用
dog = Dog("旺财", 3, "金毛")
cat = Cat("咪咪", 2, "白色")


print(f"{dog.name} 是 {dog.breed}")
dog.eat()          # 继承自父类
dog.make_sound()   # 重写的方法
dog.fetch()        # 子类特有方法


print(f"\n{cat.name} 是 {cat.color}的")
cat.sleep()         # 继承自父类
cat.make_sound()    # 重写的方法
cat.climb_tree()    # 子类特有方法

1.2.3 多态(Polymorphism)

PYTHON 复制代码
class Shape:
    def area(self):
        """计算面积(抽象方法,子类必须实现)"""
        pass  # 未实现
    
    def perimeter(self):
        """计算周长"""
        pass


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):
        return 3.14159 * self.radius ** 2
    
    def perimeter(self):
        return 2 * 3.14159 * 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
        return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5
    
    def perimeter(self):
        return self.a + self.b + self.c


# 多态的使用
def print_shape_info(shape):
    """这个函数可以处理任何Shape的子类"""
    print(f"面积: {shape.area():.2f}")
    print(f"周长: {shape.perimeter():.2f}")


# 创建不同的形状对象
shapes = [
    Rectangle(5, 10),
    Circle(7),
    Triangle(3, 4, 5)
]


# 多态调用
for i, shape in enumerate(shapes, 1):
    print(f"\n形状{i}:")
    print_shape_info(shape)
    # 自动调用对应子类的方法

第二部分:Python中的继承深度解析

2.1 继承的类型

2.1.1 单继承

PYTHON 复制代码
# 最基础的继承关系
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def introduce(self):
        return f"我叫{self.name},今年{self.age}岁"


class Student(Person):  # 单继承
    def __init__(self, name, age, student_id):
        super().__init__(name, age)  # 调用父类构造方法
        self.student_id = student_id
    
    def introduce(self):
        base_intro = super().introduce()  # 调用父类方法
        return f"{base_intro},学号是{self.student_id}"

2.1.2 多继承

PYTHON 复制代码
# 多重继承示例
class Flyable:
    def fly(self):
        return "我可以飞行"
    
    def altitude(self):
        return "我能飞到高空"


class Swimmable:
    def swim(self):
        return "我可以游泳"
    
    def depth(self):
        return "我能潜入深海"


class Runnable:
    def run(self):
        return "我可以奔跑"
    
    def speed(self):
        return "我能高速奔跑"


class Animal:
    def __init__(self, name):
        self.name = name
    
    def eat(self):
        return f"{self.name}在吃东西"


# 多重继承:一个类继承自多个父类
class Duck(Animal, Flyable, Swimmable):
    def __init__(self, name):
        Animal.__init__(self, name)  # 显式调用父类初始化
    
    def abilities(self):
        return f"{self.name}:{self.fly()},{self.swim()},还会走路"


# 多重继承:注意方法解析顺序(MRO)
class Platypus(Animal, Swimmable, Runnable):
    def __init__(self, name):
        super().__init__(name)  # 使用super()调用
    
    def abilities(self):
        return f"{self.name}:{self.swim()},{self.run()}"


# 使用
duck = Duck("唐老鸭")
print(duck.abilities())  # 唐老鸭:我可以飞行,我可以游泳,还会走路
print(duck.eat())        # 唐老鸭在吃东西


platypus = Platypus("鸭嘴兽")
print(platypus.abilities())  # 鸭嘴兽:我可以游泳,我可以奔跑


# 查看方法解析顺序
print("Duck的MRO:", Duck.__mro__)
print("Platypus的MRO:", Platypus.__mro__)

2.2 方法解析顺序(MRO)

PYTHON 复制代码
# 菱形继承问题
class A:
    def method(self):
        return "A的方法"


class B(A):
    def method(self):
        return "B的方法"


class C(A):
    def method(self):
        return "C的方法"


class D(B, C):
    pass


# Python的C3线性化算法解决菱形继承问题
d = D()
print(d.method())  # 输出:"B的方法"


# 查看MRO(Method Resolution Order)
print(D.__mro__)  # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)


# 演示MRO的实际应用
class Base:
    def __init__(self):
        print("Base.__init__()")
        self.base_value = "base"


class Left(Base):
    def __init__(self):
        print("Left.__init__()")
        super().__init__()  # 调用Base的__init__
        self.left_value = "left"


class Right(Base):
    def __init__(self):
        print("Right.__init__()")
        super().__init__()  # 调用Base的__init__
        self.right_value = "right"


class Child(Left, Right):
    def __init__(self):
        print("Child.__init__()")
        super().__init__()  # 调用Left的__init__
        self.child_value = "child"


# 创建Child实例
child = Child()
print("\n构造完成后的属性:")
print(f"child.base_value: {hasattr(child, 'base_value')}")
print(f"child.left_value: {child.left_value}")
print(f"child.right_value: {child.right_value}")
print(f"child.child_value: {child.child_value}")
print(f"\nChild类的MRO: {Child.__mro__}")

2.3 super()函数详解

PYTHON 复制代码
class BaseClass:
    def __init__(self, value):
        self.base_value = value
        print(f"BaseClass初始化,value={value}")
    
    def method(self):
        print("BaseClass.method()")
        return "base_method"


class MiddleClass1(BaseClass):
    def __init__(self, value):
        print(f"MiddleClass1初始化前")
        super().__init__(value * 2)  # 调用BaseClass.__init__
        self.middle1_value = value
        print(f"MiddleClass1初始化后")
    
    def method(self):
        print("MiddleClass1.method()前")
        result = super().method()  # 调用BaseClass.method
        print(f"MiddleClass1.method()后,父类返回: {result}")
        return f"middle1 -> {result}"


class MiddleClass2(BaseClass):
    def __init__(self, value):
        print(f"MiddleClass2初始化前")
        super().__init__(value * 3)
        self.middle2_value = value
        print(f"MiddleClass2初始化后")
    
    def method(self):
        print("MiddleClass2.method()前")
        result = super().method()
        print(f"MiddleClass2.method()后,父类返回: {result}")
        return f"middle2 -> {result}"


class DerivedClass(MiddleClass1, MiddleClass2):
    def __init__(self, value):
        print(f"DerivedClass初始化前")
        super().__init__(value)  # 根据MRO调用MiddleClass1.__init__
        self.derived_value = value
        print(f"DerivedClass初始化后")
    
    def method(self):
        print("DerivedClass.method()前")
        result = super().method()  # 根据MRO调用MiddleClass1.method
        print(f"DerivedClass.method()后,父类返回: {result}")
        return f"derived -> {result}"


# 测试
print("创建DerivedClass实例:")
derived = DerivedClass(10)


print("\n属性值:")
print(f"derived.base_value: {derived.base_value}")      # 60
print(f"derived.middle1_value: {derived.middle1_value}")  # 10
print(f"derived.middle2_value: {derived.middle2_value}")  # 10
print(f"derived.derived_value: {derived.derived_value}")  # 10


print("\n调用method方法:")
result = derived.method()
print(f"最终结果: {result}")
print(f"\nMRO顺序: {DerivedClass.__mro__}")

第三部分:抽象类深入讲解

3.1 抽象类的概念和用途

3.1.1 为什么需要抽象类?

PYTHON 复制代码
# 问题:没有抽象类的设计缺陷
class Animal:
    def speak(self):
        """预期子类必须实现这个方法"""
        # 如果子类忘记实现,运行时才会报错
        raise NotImplementedError("子类必须实现speak方法")


class Dog(Animal):
    # 忘记实现speak方法
    pass


class Cat(Animal):
    def speak(self):
        return "喵喵"


# 测试
cat = Cat()
print(cat.speak())  # 喵喵


dog = Dog()
try:
    print(dog.speak())  # 运行时才报错
except NotImplementedError as e:
    print(f"错误: {e}")  # 错误: 子类必须实现speak方法

3.1.2 使用抽象基类

PYTHON 复制代码
from abc import ABC, abstractmethod


# 抽象类定义
class Animal(ABC):  # 继承ABC表示这是抽象类
    def __init__(self, name):
        self.name = name
    
    # 抽象方法:子类必须实现
    @abstractmethod
    def speak(self):
        """动物发出声音的方法"""
        pass
    
    @abstractmethod
    def move(self):
        """动物移动的方法"""
        pass
    
    # 普通方法:抽象类可以提供实现
    def sleep(self):
        print(f"{self.name}正在睡觉")
    
    # 类方法
    @classmethod
    def get_class_info(cls):
        return f"动物类: {cls.__name__}"
    
    # 静态方法
    @staticmethod
    def is_animal(obj):
        return hasattr(obj, 'speak') and hasattr(obj, 'move')


# 子类必须实现所有抽象方法
class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed
    
    def speak(self):
        return f"{self.name}汪汪叫(品种: {self.breed})"
    
    def move(self):
        return f"{self.name}用四条腿奔跑"


class Bird(Animal):
    def __init__(self, name, wingspan):
        super().__init__(name)
        self.wingspan = wingspan
    
    def speak(self):
        return f"{self.name}叽叽喳喳叫"
    
    def move(self):
        return f"{self.name}用翅膀飞翔,翼展{self.wingspan}厘米"


# 使用抽象类
try:
    # 不能实例化抽象类
    # animal = Animal("抽象动物")  # TypeError
    pass
except TypeError as e:
    print(f"错误: {e}")


# 正确使用子类
dog = Dog("旺财", "金毛")
bird = Bird("小黄", 30)


animals = [dog, bird]
for animal in animals:
    print(f"\n{animal.name}:")
    print(f"  叫声: {animal.speak()}")
    print(f"  移动: {animal.move()}")
    animal.sleep()  # 调用父类的普通方法
    print(f"  类信息: {animal.get_class_info()}")


print(f"\n{dog.name}是动物吗?{Animal.is_animal(dog)}")  # True

3.2 抽象属性和抽象类方法

PYTHON 复制代码
from abc import ABC, abstractmethod, abstractproperty

class Vehicle(ABC):
    """交通工具抽象类"""
    
    @abstractmethod
    def __init__(self, brand, model):
        pass
    
    # 普通方法
    def drive(self, distance):
        """驾驶车辆"""
        self._mileage += distance
        return f"驾驶了{distance}公里,总里程:{self._mileage}公里"
    
    @property
    def mileage(self):
        """获取里程(属性访问器)"""
        return self._mileage


class Car(Vehicle):
    """汽车类"""
    def __init__(self, brand, model, engine_type):
        super().__init__(brand, model)
        self.engine_type = engine_type
        self._fuel_type = "汽油"
        self._max_speed = 200
    
    # 实现抽象属性
    @property
    def fuel_type(self):
        return self._fuel_type
    
    @property
    def max_speed(self):
        return self._max_speed
    
    # 实现抽象方法
    def start_engine(self):
        return f"{self.brand} {self.model} ({self.engine_type}引擎)启动"
    
    def stop_engine(self):
        return f"{self.brand} {self.model}熄火"
    
    # 子类特有方法
    def honk(self):
        return "汽车鸣笛:滴滴!"


class ElectricScooter(Vehicle):
    """电动滑板车类"""
    def __init__(self, brand, model, battery_capacity):
        super().__init__(brand, model)
        self.battery_capacity = battery_capacity
        self._fuel_type = "电力"
        self._max_speed = 25
    
    @property
    def fuel_type(self):
        return self._fuel_type
    
    @property
    def max_speed(self):
        return self._max_speed
    
    def start_engine(self):
        return f"电动滑板车{self.brand} {self.model}启动,电量{self.battery_capacity}Ah"
    
    def stop_engine(self):
        return "电动滑板车已关机"
    
    def check_battery(self):
        return f"电池状态: {self.battery_capacity}Ah"


# 使用
car = Car("丰田", "卡罗拉", "1.8L自然吸气")
scooter = ElectricScooter("小米", "Pro2", "12.8")


vehicles = [car, scooter]
for vehicle in vehicles:
    print(f"\n{vehicle.brand} {vehicle.model}:")
    print(f"  燃料类型: {vehicle.fuel_type}")
    print(f"  最高速度: {vehicle.max_speed}km/h")
    print(f"  启动: {vehicle.start_engine()}")
    print(f"  停止: {vehicle.stop_engine()}")
    
    # 调用普通方法
    print(f"  {vehicle.drive(50)}")
    print(f"  当前里程: {vehicle.mileage}公里")
    
    # 判断类型
    if isinstance(vehicle, Car):
        print(f"  特殊功能: {vehicle.honk()}")
    elif isinstance(vehicle, ElectricScooter):
        print(f"  特殊功能: {vehicle.check_battery()}")

3.3 注册虚拟子类

PYTHON 复制代码
"""
虚拟子类:允许非继承的方式将类注册为抽象基类的子类
"""
from abc import ABC, abstractmethod


class Shape(ABC):
    """形状抽象类"""
    @abstractmethod
    def area(self):
        pass
    
    @abstractmethod
    def perimeter(self):
        pass


# 方法1:使用继承
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)


# 方法2:手动注册为虚拟子类
class CustomShape:
    """自定义形状,不继承Shape但注册为虚拟子类"""
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2
    
    def perimeter(self):
        return 2 * 3.14 * self.radius


# 注册为虚拟子类
Shape.register(CustomShape)


# 方法3:使用装饰器
@Shape.register
class Triangle:
    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 (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5
    
    def perimeter(self):
        return self.a + self.b + self.c


# 测试
shapes = [
    Rectangle(5, 10),      # 继承的子类
    CustomShape(7),        # 注册的虚拟子类
    Triangle(3, 4, 5)      # 装饰器注册的虚拟子类
]


print("检查类型关系:")
for i, shape in enumerate(shapes, 1):
    print(f"\n形状{i}: {type(shape).__name__}")
    print(f"  是Shape的子类吗?{isinstance(shape, Shape)}")
    print(f"  是Shape的子类(继承检查)吗?{issubclass(type(shape), Shape)}")
    print(f"  面积: {shape.area():.2f}")
    print(f"  周长: {shape.perimeter():.2f}")


# 尝试实例化抽象类
try:
    invalid_shape = Shape()
except TypeError as e:
    print(f"\n抽象类不能实例化: {e}")

第四部分:接口与协议编程

4.1 Python中的接口概念

4.1.1 鸭子类型(Duck Typing)

PYTHON 复制代码
"""
Python的"鸭子类型"理念:
"如果它走路像鸭子,叫起来像鸭子,那么它就是鸭子"
"""
class Printer:
    def print(self, document):
        print(f"打印文档: {document}")


class Scanner:
    def scan(self, document):
        return f"扫描文档: {document}"


class Fax:
    def fax(self, document, number):
        return f"发送文档到 {number}: {document}"


# 多功能设备
class MultiFunctionDevice:
    def print(self, document):
        print(f"多功能机打印: {document}")
    
    def scan(self, document):
        return f"多功能机扫描: {document}"
    
    def fax(self, document, number):
        return f"多功能机发送传真到 {number}: {document}"


def test_printer(device):
    """测试打印功能 - 只关心有没有print方法"""
    if hasattr(device, 'print'):
        device.print("测试文档")
        return True
    return False


def test_scanner(device):
    """测试扫描功能"""
    if hasattr(device, 'scan'):
        result = device.scan("测试文档")
        print(result)
        return True
    return False


# 测试
devices = [Printer(), Scanner(), Fax(), MultiFunctionDevice()]


print("设备测试:")
for device in devices:
    print(f"\n{type(device).__name__}:")
    print(f"  打印功能: {'支持' if test_printer(device) else '不支持'}")
    print(f"  扫描功能: {'支持' if test_scanner(device) else '不支持'}")

4.1.2 使用抽象基类定义接口

PYTHON 复制代码
from abc import ABC, abstractmethod


# 定义接口
class Printable(ABC):
    @abstractmethod
    def print(self, document):
        pass


class Scannable(ABC):
    @abstractmethod
    def scan(self, document):
        pass


class Faxable(ABC):
    @abstractmethod
    def fax(self, document, number):
        pass


# 具体的类实现接口
class OldPrinter(Printable):
    def print(self, document):
        print(f"老式打印机打印: {document}")


class ModernPrinter(Printable, Scannable):
    def print(self, document):
        print(f"现代打印机打印: {document}")
    
    def scan(self, document):
        return f"现代打印机扫描: {document}"


class OfficeMachine(Printable, Scannable, Faxable):
    def print(self, document):
        print(f"办公设备打印: {document}")
    
    def scan(self, document):
        return f"办公设备扫描: {document}"
    
    def fax(self, document, number):
        return f"办公设备发送传真到 {number}: {document}"


def office_workflow(machine, document, fax_number=None):
    """办公工作流 - 要求机器实现特定接口"""
    print(f"\n开始处理文档: {document}")
    
    if isinstance(machine, Printable):
        machine.print(document)
    else:
        print("设备不支持打印")
    
    if isinstance(machine, Scannable):
        result = machine.scan(document)
        print(result)
    
    if isinstance(machine, Faxable) and fax_number:
        result = machine.fax(document, fax_number)
        print(result)


# 测试
print("办公工作流测试:")
office_workflow(OldPrinter(), "合同")
office_workflow(ModernPrinter(), "报告")
office_workflow(OfficeMachine(), "发票", "123-456-7890")


# 接口继承检查
print(f"\n接口继承关系:")
print(f"OldPrinter 是否实现 Printable? {isinstance(OldPrinter(), Printable)}")
print(f"ModernPrinter 是否实现 Scannable? {isinstance(ModernPrinter(), Scannable)}")
print(f"OfficeMachine 是否实现所有接口? {isinstance(OfficeMachine(), (Printable, Scannable, Faxable))}")

4.2 协议(Protocol)- Python 3.8+

PYTHON 复制代码
"""
Protocol:Python 3.8+ 引入的正式协议检查
允许进行静态类型检查的接口定义
"""

# 方法1:使用typing.Protocol(Python 3.8+)
from typing import Protocol, runtime_checkable
from dataclasses import dataclass

@runtime_checkable
class Drawable(Protocol):
    """可绘制对象的协议"""
    def draw(self) -> str:
        ...
    
    def erase(self) -> str:
        ...

@runtime_checkable
class Colorable(Protocol):
    """可着色对象的协议"""
    def set_color(self, color: str) -> None:
        ...
    
    def get_color(self) -> str:
        ...

# 实现协议的类
class Circle:
    def __init__(self, radius, color="黑色"):
        self.radius = radius
        self.color = color
    
    def draw(self) -> str:
        return f"绘制圆形,半径={self.radius},颜色={self.color}"
    
    def erase(self) -> str:
        return "擦除圆形"
    
    def set_color(self, color: str) -> None:
        self.color = color
    
    def get_color(self) -> str:
        return self.color
    
    # 额外的方法
    def area(self) -> float:
        return 3.14159 * self.radius ** 2

class Square:
    def __init__(self, side_length, color="黑色"):
        self.side_length = side_length
        self.color = color
    
    def draw(self) -> str:
        return f"绘制正方形,边长={self.side_length},颜色={self.color}"
    
    def erase(self) -> str:
        return "擦除正方形"

# 函数接受协议类型的参数
def draw_shape(shape: Drawable):
    print(shape.draw())

def change_color(shape: Colorable, new_color: str):
    shape.set_color(new_color)
    print(f"颜色已更改为: {shape.get_color()}")

# 使用dataclass实现协议
@dataclass
class Rectangle(Drawable, Colorable):
    width: float
    height: float
    color: str = "黑色"
    
    def draw(self) -> str:
        return f"绘制矩形,宽={self.width},高={self.height},颜色={self.color}"
    
    def erase(self) -> str:
        return "擦除矩形"
    
    def set_color(self, color: str) -> None:
        self.color = color
    
    def get_color(self) -> str:
        return self.color

# 测试
print("协议测试:")
circle = Circle(5, "红色")
square = Square(10)
rectangle = Rectangle(8, 6, "蓝色")

shapes: list[Drawable] = [circle, square, rectangle]

for i, shape in enumerate(shapes, 1):
    print(f"\n形状{i}:")
    draw_shape(shape)
    
    # 检查是否实现Colorable协议
    if isinstance(shape, Colorable):
        change_color(shape, "绿色")
        print(shape.draw())
    else:
        print("该形状不支持颜色设置")

# 协议继承检查
print(f"\n协议实现检查:")
print(f"Circle 实现 Drawable? {isinstance(circle, Drawable)}")
print(f"Circle 实现 Colorable? {isinstance(circle, Colorable)}")
print(f"Square 实现 Drawable? {isinstance(square, Drawable)}")
print(f"Square 实现 Colorable? {isinstance(square, Colorable)}")
print(f"Rectangle 实现 Drawable? {isinstance(rectangle, Drawable)}")
print(f"Rectangle 实现 Colorable? {isinstance(rectangle, Colorable)}")

总结

我们已经完成了Python抽象类、接口和继承的系统学习!让我们回顾一下重点:

关键概念:

  1. 封装:隐藏实现细节,通过公共接口访问
  2. 继承:代码复用和层次结构
  3. 多态:同一操作作用于不同对象产生不同行为
  4. 抽象类:不能实例化,定义接口和部分实现
  5. 接口:定义契约,不包含实现(Python通过协议实现)

实际应用场景:

  1. 框架开发:定义通用接口
  2. 插件系统:允许第三方扩展
  3. API设计:提供稳定的接口
  4. 代码复用:提取公共功能到基类

最佳实践:

  1. 优先使用组合而不是继承
  2. 保持继承层次浅
  3. 使用抽象类和接口定义契约
  4. 遵守SOLID原则
  5. 适当使用设计模式
相关推荐
无风听海3 小时前
ASP.NET Core .NET 10 错误响应体系全景:从 BadRequest 到编译器基础设施
后端·asp.net·.net
文心快码BaiduComate3 小时前
从个人效能到组织资产:文心快码企业版Agent Hub上线,提升团队AI编程效能
前端·后端·程序员
雪隐4 小时前
个人电脑玩AI00-前言
人工智能·后端
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题 第89题】【Mysql篇】第19题:Hash 索引和 B+ 树索引的区别?它们在使用方面的区别?
java·数据库·mysql·面试·哈希算法
我是一颗柠檬4 小时前
【Java后端技术亮点】动态路由权限(按钮级权限),细粒度控制到按钮级别
java·开发语言·后端·状态模式
前端Hardy4 小时前
CSS 动画真的比 JS 快?Josh Comeau 做了组实验,结果跟直觉不一样
前端·javascript·后端
Front思4 小时前
调取支付宝支付正式环境不可以唤起来,但是沙箱可以
后端
foggyprojects4 小时前
AI 生成 SQL 模板以后,为什么还需要固定 helper 规则
后端
明天一点4 小时前
Cloudflare 通知转发钉钉机器人
前端·后端
前端Hardy4 小时前
前端日历组件,要变天了?Schedule-X v4.6 彻底杀疯了
前端·javascript·后端