Let us jump right into it. No BS!
Import the ABC
(Abstract Base Class) module and abstractmethod from the abc
module in Python. The ABC
module is used for defining abstract base classes.
from abc import ABC, abstractmethod
Now, to create a new abstract base class, we simply need to create a class.
Here, we will call it Shape
and it inherits from ABC Shape(ABC)
The abstractmethod
decorator is used to declare abstract methods within an abstract class.
class Shape(ABC):
@abstractmethod
def area(self):
"""Abstract method to calculate the area of the shape."""
pass
@abstractmethod
def perimeter(self):
"""Abstract method to calculate the perimeter of the shape."""
pass
That's it! you've just defined an abstract base class.
In this example, Shape
is an abstract base class with two abstract methods: area
and perimeter
.
We can have pass
for method area
and perimeter
because they don't do anything in Shape
class definition. They don't contain an implementation in abstract class.
We provide implementation for the abstract methods via subclasses. For this example we create two subclasses Circle
and Square
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
def perimeter(self):
return 2 * 3.14 * self.radius
class Square(Shape):
def __init__(self, length):
self.length = length
def area(self):
return self.length * self.length
def perimeter(self):
return 4 * self.radius
To be valid child of Shape
, we need to define area
and perimeter
for the subclasses. The Circle
and Square
classes are subclasses of Shape
and provide concrete implementations for the abstract methods.
We can now create objects for classes circle
and square
circle = Circle(radius=5)
square = Square(length=4)
print("Circle Area: ", circle.area())
print("Square Area: ", square.area())
print("Circle Perimeter: ", circle.perimeter())
print("Square Perimeter: ", square.perimeter())
Now our final code looks something like this.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
"""Abstract method to calculate the area of the shape."""
pass
@abstractmethod
def perimeter(self):
"""Abstract method to calculate the perimeter of the shape."""
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
def perimeter(self):
return 2 * 3.14 * self.radius
class Square(Shape):
def __init__(self, length):
self.length = length
def area(self):
return self.length * self.length
def perimeter(self):
return 4 * self.length
circle = Circle(radius=5)
square = Square(length=4)
print("Circle Area: ", circle.area())
print("Square Area: ", square.area())
print("Circle Perimeter: ", circle.perimeter())
print("Square Perimeter: ", square.perimeter())
Let us not implement a method from subclass. You can remove any. Here, I have removed perimeter method from Square
class.
class Square(Shape):
def __init__(self, length):
self.length = length
def area(self):
return self.length * self.length
When you run the program after removing a method from a subclass, you will receive an error message.
TypeError: Can't instantiate abstract class Square without an implementation for abstract method 'perimeter'
This means that any concrete subclass of Shape
must provide its own implementation of area
and perimeter
. If a subclass fails to do so, it will result in a TypeError
during instantiation.
This example demonstrates the usefulness of abstract base class in ensuring a consistent interface. It helps to avoid unintended mistakes and ensures a consistent interface for all subclasses when collaborating with others and working on a large project, where maintaining a clear and predictable structure is crucial.
So, in a nutshell, importing ABC
and abstractmethod
from the abc
module allows you to create abstract classes with abstract methods in Python. Subclasses of these abstract classes need to provide their own implementations for the abstract methods.