python中的抽象基类ABC

python中的抽象基类(ABC,Abstract Base Class)相当于是Java中的接口,抽象基类就是定义各种方法而可以不做具体实现的类,当然也可以实现,只不过子类如果想调用抽象基类中定义的方法需要使用super()


抽象基类的使用:
1、直接继承
直接继承抽象基类的子类就没有这么灵活,抽象基类中可以声明”抽象方法“和“抽象属性”,只有完全覆写(实现)了抽象基类中的“抽象”内容后,才能被实例化,而虚拟子类则不受此影响。
2、虚拟子类
将其他的类”注册“到抽象基类下当虚拟子类(调用register方法),虚拟子类的好处是你实现的第三方子类不需要直接继承自基类,可以实现抽象基类中的部分API接口,也可以根本不实现,但是issubclass(), issubinstance()进行判断时仍然返回真值。



python中并没有提供抽象类与抽象方法,但是提供了内置模块abc(abstract base class)来模拟实现抽象类。

例:
定义一个抽象基类的简单方法: 首先在Dog,Duck都继承自Animal。 在Animal中定义了eat和run两个方法,任何从Animal中继承的子类都必须实现eat和voice方法。否则调用的时候会报错

例:

class Animal(object):
    def eat(self):
        raise NotImplementedError

    def run(self):
        raise NotImplementedError

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()
duck.run()

# 结果
dog is eating
dog is running
duck is eating
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 83, in 
    duck.run()
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 59, in run
    raise NotImplementedError
NotImplementedError

以上的大家开始学习实现的方式,这种实现当调用方法的时候才会报错,在实际情况中存在不合理之处,当duck实例化成功后就应该具有eat、run行为,鸭子生下来就应该会吃会跑,所以我们需要的是如果没有实现eat或run方法,实例化就应该是失败的

修改代码如下:

import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def run(self):
        pass

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()


#结果 
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 80, in 
    duck = Duck()
TypeError: Can't instantiate abstract class Duck with abstract methods run

结果显示无法实例化,提示没有实现eat方法。这样就达到了我们的目的即没有实现抽象基类的所有方法就无法实例化

你可能感兴趣的:(python)