Python抽象类

Python抽象类

python没有接口类型,因为python是动态类型的语言,像接口这种轻耦合的东西在python中随处都是,例如内置的魔法方法等,甚至可以说在python这种天马行空的语言中接口显的反而有点清秀。

不过Python还是提供了像java中那样的抽象类定义方法,某些时候还是有用的,顾名思义抽象类就是对一些实体类的抽象定义,其出现的主要目的就是为了描述某一类拥有相同方法的类。

抽象类是介于普通的类继承和接口之间的一种中庸之道,他与接口之间的差别不大,甚至可以说能用抽象类处理的实际上都可以用接口处理。

用更加通俗的语言来描述抽象类:

  1. 抽象类当中的抽象方法可以没有具体实现,只需要定义函数名和输入输出即可(python中输入输入亦可省)
  2. 抽象类不能被直接实例化,只有实现了其抽象方法的子类才能实例化
  3. 抽象类的子类必须实现抽象方法

为什么需要抽象类?
1.我们想要为多个实体类定义一个父类,但是我们不想让父类直接实例化,因为父类的实例化没有意义。举个例子,我们定义一个动物类,他有一个sing()方法,但是每种动物的叫声都不一样,直接实例化Animal没有任何意义,我们只是想让他抽象出sing方法来:

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

    def sing(self):
        pass

    def say_name(self):
        print(self.name)

这样的普通Animal类可以实例化,但是之后呢,其sing方法完全是失效的,同时继承的子类并不强制要求实现sing方法,要求太宽松了。

class AnimalBaseClass(abc.ABC):
    @abc.abstractmethod
    def sing(self):
        pass

    def say_name(self):
        print(self.name)

抽象类就不一样了,他直接禁止你实例化AnimalBaseClass,同时要求子类必须实现sing方法,哪怕你在子类的sing中直接pass也行,但必须得有,这样我们可以确保子类的sing方法有意义(如果在子类中继续定义sing() pass那是你子类的错和我抽象类有什么关系~~)。

当然对于say_name方法直接使用就可以,这点和普通父类继承一样,所以可以看到抽象类也可以定义普通方法(非抽象方法),甚至可以这么说:除了抽象方法外,抽象类其他的定义就和普通父类一样即可,可以定义__init__()方法,子类初始化时也可以直接使用super().__init__来初始化一部分属性。

2.所以我们为什么需要抽象类?
答案是当然非必须啊,你要喜欢继承普通父类并且随意的重载和增加方法都随意,但是定义抽象类可以使代码更加有逻辑,在规则的驱使下大型项目可以更加便于协作的和后期维护,这个多接触一些项目就明白了。
使用抽象类或接口的另一大好处是,当在其他地方需要统一处理某一大类对象时,我们可以直接使用抽象类型or接口类型作为输入,此时使用任意子类作为输入都合法,这样可以避免繁复的子类类型判断或编写多个函数。

在Python中我们需要借助内置的抽象基类帮助定义抽象类:

from abc import ABC, abstractmethod

class MyBaseClass(ABC):
    @abstractmethod
    def my_abstract_method(self):
        pass

    def my_regular_method(self):
        return "Hello from MyBaseClass"

class MyDerivedClass(MyBaseClass):
    def my_abstract_method(self):
        return "Hello from MyDerivedClass"
my_derived_instance = MyDerivedClass()
print(my_derived_instance.my_abstract_method())  # Output: Hello from MyDerivedClass
print(my_derived_instance.my_regular_method())   # Output: Hello from MyBaseClass

其中@abstractmethod用于标识一个必须被子类实现的抽象方法,不同于java当中对抽象类定义和继承的各种限制,在python中我们只要继承ABC类即可定义出一个抽象类,其他的地方随你怎么写。

通常情况的,在python中你没有必要定义抽象类,因为抽象类相当于规则的制定者,一般这种角色在开源库或标准包中较为常见,例如xxxBaseClass,当你看到base class这种命名时可以额外注意下,普通父类一般不会这么命名,只有作为其他实体类的抽象基类时才会约定命名为此。

posted @ 2023-05-31 11:16  realcp1018  阅读(405)  评论(0编辑  收藏  举报