Introduction
Abstract base classes (ABCs) are used to create classes which are not intended to be instantiated directly, because there is no functionality, only a "template" of what attributes and methods are available. Instead, you create a child class that inherits from the ABC, implement stuff in the child class, and inherit from that. (The StackOverflow abstract-class
tag defines them as follows: "Abstract classes are classes which cannot be instantiated. They exist to provide common functionality and interface specifications to several concrete classes.")
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def dream(self):
pass
We cannot create an instance of Animal
directly:
>>> Animal()
TypeError: Can't instantiate abstract class Animal with abstract methods dream
But we can make a subclass which implements dream
, and instantiate that:
class Human(Animal):
def dream(self):
return "Electric sheep"
Human()
Question
Note that my ABC (Animal
) both inherits from the ABC
class and defines the dream
method as being an abstractmethod
. I don't understand why both are necessary.
Details
If I hadn't made the dream
method an abstractmethod
, then my ABC doesn't actually function as an ABC, because you can instantiate it, even though I was expecting it to complain to me about instantiating ABC:
class Animal(ABC):
def dream(self):
pass
barbapapa = Animal() # Not a specific subclass of Animal. Still works.
barbapapa.dream()
Had I made dream
an abstractmethod
, but made my Animal
class not inherit from ABC
, I would still be able to instantiate it:
class Animal(object):
@abstractmethod
def dream(self):
pass
barbapapa = Animal() # Not a specific subclass of Animal. Still works.
barbapapa.dream()
And this works too! The abstractmethod
decoration doesn't seem to do anything without inheriting from ABC
.
I understand that a class inheriting from ABC
shouldn't mean that you can't create instances of that class. (After all, the classes inheriting from my Animal
class should be able to be instantiated, even though those classes indirectly inherit from ABC
as well.)
But then why is inheriting from ABC
necessary at all? Why not just made it so that you cannot instantiate any class that has abstractmethod
s (or properties, or whatnot)?