I'm trying to understand the benefits of using abstract base classes. Consider these two pieces of code:
Abstract base class:
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
Plain inheritance:
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
As you see, both methods support inflection using isinstance
and issubclass
.
Now, one difference I know is that, if you try to instantiate a subclass of an abstract base class without overriding all abstract methods/properties, your program will fail loudly. However, if you use plain inheritance with NotImplementedError
, your code won't fail until you actually invoke the method/property in question.
Other than that, what makes using abstract base class different?