Define interfaces in python

Define interfaces in python

Abstract Base Class - Basic

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.