Python中14个让你代码更灵活的继承和多态应用

1. 基础继承:让类共享属性和方法

  • 概念讲解:继承允许子类(派生类)继承父类(基类)的属性和方法。这是代码复用的关键。

  • 实践示例

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

dog = Dog("Buddy")
print(dog.speak())  # 输出: Woof!

解释Dog类从Animal类继承,重写了speak方法,展示了继承的基本用法。

2. 方法重写:定制行为

  • 技巧:子类可以重写父类的方法以改变或扩展其行为。

  • 实例

class Cat(Animal):
    def speak(self):
        return "Meow!"
cat = Cat("Whiskers")
print(cat.speak())  # 输出: Meow!

3. 超(super)函数:调用父类方法

  • 深入:使用super()函数可以在子类中调用父类的方法。

  • 代码

class Animal:
    def __init__(self, name):
        self.name = name

class Mammal(Animal):
    def __init__(self, name, fur_color):
        super().__init__(name)  # 调用父类构造器
        self.fur_color = fur_color

注意:这保持了代码的连贯性,易于理解。

4. 抽象基类(ABC):规范子类实现

  • 专业提升:通过abc模块定义抽象方法,强制子类实现特定接口。

  • 示例

from abc import ABC, abstractmethod

class Vehicle(ABC):
    @abstractmethod
    def start(self):
        pass

class Car(Vehicle):
    def start(self):
        return "Engine started."

解释Vehicle是抽象基类,start是抽象方法,必须在子类中实现。

5. 多重继承:融合多个类的功能

  • 灵活性展示:一个类可以从多个父类继承。

  • 例子

class Flyer:
    def fly(self):
        return "Flying high."

class Swimmer:
    def swim(self):
        return "Swimming in the lake."

class Duck(Flyer, Swimmer):
    pass

duck = Duck()
print(duck.fly())  # 输出: Flying high.
print(duck.swim())  # 输出: Swimming in the lake.

注意点:顺序很重要,Python遵循MRO(方法解析顺序)来决定先调用哪个类的方法。

6. 方法重载:Python中的变体

  • 技巧提示:Python不直接支持传统意义上的方法重载,但可以通过参数默认值、关键字参数等间接实现。

  • 模拟重载

class Calculator:
    def add(self, a=0, b=0, c=0):
        return a + b + c

calc = Calculator()
print(calc.add(1, 2))  # 输出: 3
print(calc.add(1, 2, 3))  # 输出: 6

7. 静态方法和类方法:非实例依赖

  • 静态方法:通过@staticmethod,无需实例或类上下文。

  • 类方法:通过@classmethod,第一个参数为类本身。

  • 示例

class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b

    @classmethod
    def multiply(cls, a, b):
        return cls._multiply(a, b)

    @staticmethod
    def _multiply(a, b):
        return a * b

print(MathUtils.add(5, 3))  # 输出: 8
print(MathUtils.multiply(5, 3))  # 输出: 15

实践意义:适用于工具类,减少实例化需求。

8. 多态:接口一致,行为多样

  • 核心概念:不同的对象可以对同一消息做出响应,实现不同行为。

  • 演示

def make_sound(animal):
    return animal.speak()

dog = Dog("Rex")
cat = Cat("Luna")
print(make_sound(dog))  # 输出: Woof!
print(make_sound(cat))  # 输出: Meow!

关键点:多态减少了代码耦合,提高了代码的可扩展性。

9. 属性描述符:控制属性访问

  • 高级特性:使用描述符类来控制类属性的访问逻辑。

  • 应用

class NonNegative:
    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError(f"{self.name} cannot be negative.")
        instance.__dict__[self.name] = value

class NumberHolder:
    number = NonNegative()

holder = NumberHolder()
holder.number = 5
try:
    holder.number = -1
except ValueError as e:
    print(e)  # 输出: number cannot be negative.

学习价值:深入理解Python对象模型,实现更精细的属性管理。

10. 装饰器与继承结合:增强功能

  • 综合运用:装饰器可以用来动态增加类或方法的功能,与继承共同作用。

  • 示例

def log_decorator(cls):
    original_speak = cls.speak

    def speak(self):
        print(f"{self.name} is about to speak.")
        return original_speak(self)

    cls.speak = speak
    return cls

@log_decorator
class TalkativeDog(Dog):
    pass

my_dog = TalkativeDog("Charlie")
print(my_dog.speak())  # 先输出: Charlie is about to speak., 然后: Woof!

11. 元类(Metaclasses):控制类的行为

  • 深度探索:元类允许你在创建类时进行干预,是Python中非常底层且强大的特性。

  • 示例

class Meta(type):
    def __new__(cls, name, bases, dct):
        if 'count' not in dct:
            dct['count'] = 0
        return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=Meta):
    def __init__(self):
        self.count += 1

obj1 = MyClass()
obj2 = MyClass()
print(MyClass.count)  # 输出: 2

注意事项:元类使用需谨慎,过度使用会增加代码复杂度。

12. 使用__slots__优化内存使用

  • 性能提升:通过限制实例能拥有的属性,减少内存占用。

  • 应用

class Person:
    __slots__ = ('name', 'age')  # 限定属性

p1 = Person()
p1.name = "Alice"
p1.age = 30
# p1.address = "Somewhere"  # 这会引发AttributeError,因为address未被允许

print(p1.name, p1.age)

小贴士__slots__减少了每个实例的开销,但限制了灵活性,不适合所有场景。

13. 继承与封装:保护内部状态

  • 设计原则:使用私有(前缀双下划线__)和保护(单下划线_)成员来管理类的内部状态。

  • 实践

class Base:
    def __init__(self):
        self._protected_var = 0
        self.__private_var = 0

class Derived(Base):
    def modify_protected(self):
        self._protected_var += 1  # 可访问,但不推荐修改父类的保护属性

    # 尝试访问私有属性会失败
    # def access_private(self):
    #     print(self.__private_var)  # 错误:尝试访问私有属性

base = Base()
derived = Derived()
derived.modify_protected()

理解:虽然Python没有严格的访问控制,但通过命名约定传达意图,保护数据完整性。

14. 多态与策略模式

  • 设计模式:策略模式利用多态性,根据上下文切换算法或行为。

  • 示例

from abc import ABC, abstractmethod

class Strategy(ABC):
    @abstractmethod
    def do_algorithm(self, data):
        pass

class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data):
        return sorted(data)

class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data):
        return reversed(sorted(data))

class Context:
    def __init__(self, strategy):
        self._strategy = strategy

    @property
    def strategy(self):
        return self._strategy

    @strategy.setter
    def strategy(self, strategy):
        self._strategy = strategy

    def do_some_business_logic(self, data):
        result = self._strategy.do_algorithm(data)
        print(",".join(map(str, result)))

data = [1, 2, 3]
context = Context(ConcreteStrategyA())
context.do_some_business_logic(data)  # 输出按升序排列的数据
context.strategy = ConcreteStrategyB()  # 切换策略
context.do_some_business_logic(data)  # 输出按降序排列的数据

学习要点:策略模式通过替换策略对象,而非修改算法,实现了行为的多样化,体现了多态的强大之处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值