Python基础(二十八、多态、抽象类)


在面向对象编程中,多态是一种强大的概念,它允许不同类型的对象对相同的消息做出不同的响应。Python作为一门支持面向对象编程的语言,也支持多态。

一、什么是多态?

多态(Polymorphism)是指在面向对象编程中,不同类型的对象可以使用相同的接口,而具体的实现方式则各不相同。
换句话说,当我们调用一个方法时,不同的对象可以以不同的方式来响应这个方法调用。
这种极大地提高了代码的可复用性和可扩展性。
多态即是面向对象编程的三大特性之一,另外两个是封装和继承。

二、多态的实现

Python通过动态类型语言的特点来实现多态,即在运行时根据实际对象的类型进行方法调用。具体来说,Python中的多态实现依赖于以下两个特性:

  • 动态绑定(Dynamic Binding):在运行时根据对象的类型确定方法的具体实现;
  • 鸭子类型(Duck Typing):只要一个对象“走起路来像鸭子、叫起来像鸭子”,那么它就可以被视为鸭子。

1.通过继承实现多态

下面通过一个例子来说明Python中的多态实现:

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError('Subclass must implement abstract method')

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

class Cat(Animal):
    def speak(self):
        return 'Meow!'

def animal_speak(animal):
    print(animal.speak())

dog = Dog('Tommy')
cat = Cat('Kitty')

animal_speak(dog)  # 输出:Woof!
animal_speak(cat)  # 输出:Meow!

在上面的例子中,我们定义了一个Animal类和两个子类Dog和Cat,它们分别实现了speak()方法。
animal_speak()函数接受任何一个Animal对象,并调用其speak()方法。
由于Python是动态类型语言,因此在运行时可以根据实际传入的对象类型确定调用哪个speak()方法。

2.抽象类实现多态

抽象类是一种只能被继承而不能被实例化的类。它定义了一个通用的接口,子类必须实现这个接口中定义的方法或属性。抽象类的存在可以让我们在设计和编写代码时更加灵活和规范。抽象类的主要作用有两个:

  • 提供一种规范:抽象类定义了子类应该具备的方法或属性,确保了子类的一致性。
  • 强制子类实现:抽象类要求子类必须实现抽象类中定义的方法或属性,否则会在运行时抛出异常。

2.1 抽象类的实现

Python中的抽象类通过abc模块来实现。该模块提供了ABC(Abstract Base Class)类和abstractmethod装饰器,用于定义抽象类和抽象方法。
语法:

from abc import ABC, abstractmethod

class 类名(ABC):
	@abstractmethod
    def 函数名(self):
    	pass或者逻辑

下面是一个简单的示例:

from abc import ABC, abstractmethod

class AbstractClassExample(ABC):
    
    @abstractmethod
    def method1(self):
        pass
    
    @abstractmethod
    def method2(self):
        pass

class ConcreteClassExample(AbstractClassExample):
    
    def method1(self):
        print("Method 1 implementation")
    
    def method2(self):
        print("Method 2 implementation")

# 抽象类无法实例化
# example = AbstractClassExample()

# 子类可以实例化并调用方法
example = ConcreteClassExample()
example.method1()  # 输出:"Method 1 implementation"
example.method2()  # 输出:"Method 2 implementation"

在上面的示例中,AbstractClassExample是一个抽象类,它继承自ABC类。method1()和method2()被abstractmethod装饰器修饰,表示它们是抽象方法,子类必须实现这两个方法。

ConcreteClassExample是一个具体类,它继承自AbstractClassExample。
由于ConcreteClassExample重写了method1()和method2(),因此它可以实例化并调用这两个方法。

2.2 抽象类的注意事项

在使用抽象类时,需要注意以下几点:

  • 抽象类不能被实例化:抽象类只能用作其他类的基类,不能直接创建实例。
  • 子类必须实现所有抽象方法:子类必须实现抽象类中定义的所有抽象方法,否则会在运行时抛出异常。如果子类没有实现所有抽象方法,它也会被视为抽象类。
  • 抽象方法可以有实现:抽象方法可以在抽象类中有默认实现,但子类仍然可以选择重写这些方法。
  • 抽象类可以包含非抽象方法:抽象类中除了抽象方法外,还可以包含普通的方法和属性。

2.3 总结

抽象类是一种不能被实例化的类,它定义了其他类的通用接口和行为。Python通过abc模块来实现抽象类,使用ABC类作为基类和abstractmethod装饰器来定义抽象类和抽象方法。使用抽象类可以提供代码的规范性和灵活性,强制子类实现抽象方法,从而提高代码的可靠性和可维护性。然而,在使用抽象类时,需要注意抽象类不能被实例化、子类必须实现所有抽象方法等事项。

三、注意事项

虽然多态可以提高代码的可复用性和可扩展性,但也需要注意一些问题。

  • 抽象基类应该定义规范的接口,确保所有实现该接口的子类都能够正确地响应相应的方法调用。
  • 尽管Python是一门动态类型语言,但仍然需要注意调用的方法是否存在,以避免在运行时抛出AttributeError异常。
  • 当有多个子类实现了同一个方法时,需要确保每个子类的实现方式是相互独立的,以避免意外地影响其他子类的正确性。

四、总结

多态是面向对象编程中非常重要的一个概念,它可以提高代码的可复用性和可扩展性。
Python作为一门支持面向对象编程的语言,通过动态类型语言的特点来实现多态,即在运行时根据实际对象的类型进行方法调用。同时,我们也需要注意抽象基类的规范定义、方法调用的存在性以及子类实现方式相互独立等问题。

随笔练习抽象类

from abc import ABC,abstractmethod

"""
1.需要使用abc模块实现抽象类,即定义抽象类的时候需要class 抽象类名称(ABC):
2.实现抽象类,要将抽象方法都实现
3.抽象类不能被实例化,会报错TypeError: Can't instantiate abstract class Animal with abstract methods cood, speak
4.抽象类中可以有构造函数,可以有普通函数
5.抽象方法可以有实现
"""
class Animal(ABC):
    def __init__(self,type):
        self.type = type

    def speak(self):
        print("要吃冻干")

    @abstractmethod
    def speak(self):
        pass

    # 抽象方法可以有实现
    @abstractmethod
    def cood(self):
        print("要吃冻干")


class Cat(Animal):
    color = None

    def speak(self):
        print("要吃冻干")
    def cood(self):
        print("要吃冻干")

cat = Cat("1")
cat.speak()

相关推荐

  1. Python基础抽象

    2024-01-13 11:16:03       68 阅读
  2. Python编程的面向对象()—

    2024-01-13 11:16:03       30 阅读
  3. 与对象、抽象、封装、继承、以及举例

    2024-01-13 11:16:03       31 阅读
  4. go语言()----

    2024-01-13 11:16:03       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-13 11:16:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-13 11:16:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-13 11:16:03       82 阅读
  4. Python语言-面向对象

    2024-01-13 11:16:03       91 阅读

热门阅读

  1. Android 13(T) - Media框架(3)- mediaserver

    2024-01-13 11:16:03       50 阅读
  2. 【RUST】请为get_local_info提出宝贵意见

    2024-01-13 11:16:03       51 阅读
  3. 换根DP求树的重心/求最小距离和

    2024-01-13 11:16:03       56 阅读
  4. pythonrequests用法

    2024-01-13 11:16:03       55 阅读
  5. 【C】存储类别(作用域、链接、存储期)

    2024-01-13 11:16:03       53 阅读
  6. js null和undefined的区别

    2024-01-13 11:16:03       42 阅读
  7. CNAS中兴新支点——软件验收测试功能有哪些

    2024-01-13 11:16:03       50 阅读
  8. Qt QML和QWidget混合编程(面试亮点)

    2024-01-13 11:16:03       59 阅读
  9. [论文笔记] PAI-Megatron中qwen和mistral合并到Megtron-LM

    2024-01-13 11:16:03       60 阅读
  10. openssl3.2 - 官方demo学习 - client-conf.c

    2024-01-13 11:16:03       56 阅读
  11. Python中的图像处理和计算机视觉应用

    2024-01-13 11:16:03       58 阅读