An abstract base class is a class that is used as a blueprint for other classes. Abstract base classes are a powerful feature in Python since they help us define a blueprint for other classes that may have something in common.
Fruits are a general term for something natural that we can eat – they are usually sweet, colorful, and have a shape. Now, that is a general overview of what a fruit is. However, might have a specific kind of fruit like a mango. Let’s say we have a normal mango and a wild mango. The normal one is usually sweeter than the wild mango, but both are mangoes, and mango is a fruit.
It is not possible for a fruit to exist that has no color or shape.
You can think of Fruit
as a base class or metaclass for the mango class. Under the mango class, we can have two instances of mango, wild mango and normal mango. It should have a color and a shape, or it won’t make any sense.
Abstract base classes are similar to the case of the fruit. An abstract base class is defined on that which other classes will be based. Those other classes cannot exist if they don’t have the attributes and or methods of the abstract base class.
An abstract base class is “Abstract” because it is non-existent – it’s just an ideal way for some other class to exist, but it cannot exist on its own.
Python provides an easy way of creating an abstract base class through a built-in module called abc (Stands for Abstract Base Class).
We will use the example of the fruit to create our class. Throughout this tutorial, I will make use of the abbreviation ABC to represent Abstract Base Class.
Here is a simple ABC:
from abc import ABCMeta, abstractmethod
class Fruit(metaclass=ABCMeta):
@abstractmethod
def getshape(self):
print(self.shape)
@abstractmethod
def getcolor(self):
return self.color
@abstractmethod
def gettaste(self):
return self.taste
class Mango(Fruit):
def __init__(self, taste="Sweet"):
self.shape = "Oval"
self.taste = taste
self.color = "Orange"
def getshape(self):
return self.shape
def getcolor(self):
return self.color
def gettaste(self):
return self.taste
normal_mango = Mango()
wild_mango = Mango("Sour")
print(wild_mango.gettaste())
In the code above, we have created a blueprint for a fruit class. We then create a method that all other classes will inherit from. Since we want the getshape()
method to be inherited by all other classes, we add the @abstractmethod
decorator to it.
We then create Mango
class, which is based on Fruit
. Our fruit should have a shape, so we add it to the initializer. We then add the getshape()
method so we can get the shape of the Mango. You can probably guess the remaining lines – we are just creating an instance of Mango and calling getshape()
to get the shape.
Let’s create another class that will be based on the Fruit class.
This time, let’s ignore the gettaste()
method and see what happens.
Add the following code:
class Orange(Fruit):
def __init__(self):
self.color = "Orange"
self.shape = "Spherical"
def getshape(self):
return self.shape
def getcolor(self):
return self.color
my_orange = Orange()
Now, run the code. You may notice we get an error telling us that we cannot instantiate an orange unless we have implemented the gettaste()
method.
Just like in our fruits example, our orange cannot exist unless we can get its taste.
Modify the code to look like:
class Orange(Fruit):
def __init__(self):
self.taste = "Sweet"
self.color = "Orange"
self.shape = "Spherical"
def getshape(self):
return self.shape
def getcolor(self):
return self.color
def gettaste(self):
return self.taste
my_orange = Orange()
If we run the code above, we don’t get an error again. This is because we can now get the taste of our fruit.
The final code should look similar to this:
from abc import ABCMeta, abstractmethodclass Fruit(metaclass=ABCMeta):@abstractmethoddef getshape(self):print(self.shape)@abstractmethoddef getcolor(self):return self.color@abstractmethoddef gettaste(self):return self.tasteclass Mango(Fruit):def __init__(self, taste="Sweet"):self.shape = "Oval"self.taste = tasteself.color = "Orange"def getshape(self):return self.shapedef getcolor(self):return self.colordef gettaste(self):return self.tastenormal_mango = Mango()wild_mango = Mango("Sour")print(wild_mango.gettaste())class Orange(Fruit):def __init__(self):self.taste = "Sweet"self.color = "Orange"self.shape = "Spherical"def getshape(self):return self.shapedef getcolor(self):return self.colordef gettaste(self):return self.tastemy_orange = Orange()
This answer has just scratched the surface of ABC on python. I recommend you to go through Python documentation to learn more about them, here.