我正在尝试理解使用抽象基类的好处。考虑以下这两个代码片段:
抽象基类:
from abc import ABCMeta, abstractmethod, abstractproperty
class CanFly:
__metaclass__ = ABCMeta
@abstractmethod
def fly(self):
pass
@abstractproperty
def speed(self):
pass
class Bird(CanFly):
def __init__(self):
self.name = 'flappy'
@property
def speed(self):
return 1
def fly(self):
print('fly')
b = Bird()
print(isinstance(b, CanFly)) # True
print(issubclass(Bird, CanFly)) # True
简单继承:
class CanFly(object):
def fly(self):
raise NotImplementedError
@property
def speed(self):
raise NotImplementedError()
class Bird(CanFly):
@property
def speed(self):
return 1
def fly(self):
print('fly')
b = Bird()
print(isinstance(b, CanFly)) # True
print(issubclass(Bird, CanFly)) # True
正如你所看到的,这两种方法都支持使用 isinstance
和 issubclass
进行词形变化。
现在,我知道的一个区别是,如果尝试实例化抽象基类的子类而没有覆盖所有抽象方法/属性,则程序将会报错。然而,如果使用带有 NotImplementedError
的普通继承,直到实际调用相关方法/属性时,代码才会失败。
除此之外,使用抽象基类还有什么不同之处吗?