Python Abstract Base Classes (ABCs)

Well, they’re like the cool kids in high school who get to wear their own uniform and have special privileges. Except instead of being popular, ABCs help you write better code by enforcing certain rules on your classes.

Here’s how it works: let’s say you want to create a class for animals that can swim. You might think something like this:

# This script creates a class for animals that can swim

class AnimalSwimmer:
    # This is the constructor method that initializes the class with a name attribute
    def __init__(self, name):
        self.name = name
        
    # This method prints a message indicating that the animal is swimming
    def swim(self):
        print("I am swimming!")

But what if you also want to create a class for animals that can fly? You could copy and paste the `__init__()` method from `AnimalSwimmer`, but then you’d have duplicate code. And what if there are other common methods between animal classes, like `make_noise()` or `eat()`?

That’s where ABCs come in! Instead of copying and pasting code, we can create an abstract base class (ABC) that defines the required methods for all animals. Then, our specific animal classes will inherit from this ABC and implement their own versions of those methods:

# Importing the ABC module from the abc library
from abc import ABC, abstractmethod

# Creating an abstract base class called Animal
class Animal(ABC):
    # Defining an abstract method called make_noise
    @abstractmethod
    def make_noise(self):
        pass
        
    # Defining an abstract method called eat
    @abstractmethod
    def eat(self):
        pass
        
# Creating a class called SwimmerAnimal that inherits from the Animal class
class SwimmerAnimal(Animal):
    # Defining the constructor method that takes in a name parameter
    def __init__(self, name):
        # Assigning the name parameter to the name attribute
        self.name = name
    
    # Defining a method called swim
    def swim(self):
        # Printing a message to indicate that the animal is swimming
        print("I am swimming!")
        
    # Implementing the make_noise method from the Animal class
    def make_noise(self):
        # Printing a message to indicate the noise the animal makes
        print("Splash!")
        
# Creating a class called FlyerAnimal that inherits from the Animal class
class FlyerAnimal(Animal):
    # Defining the constructor method that takes in a name parameter
    def __init__(self, name):
        # Assigning the name parameter to the name attribute
        self.name = name
    
    # Defining a method called fly
    def fly(self):
        # Printing a message to indicate that the animal is flying
        print("I am flying!")
        
    # Implementing the make_noise method from the Animal class
    def make_noise(self):
        # Printing a message to indicate the noise the animal makes
        print("Tweet tweet!")

In this example, we’ve created an `Animal` ABC that defines the required methods for all animals. The `SwimmerAnimal` and `FlyerAnimal` classes inherit from `Animal`, but they also have their own unique methods (like `swim()` or `fly()`) that are specific to each type of animal.

The `@abstractmethod` decorator tells Python that these methods must be implemented in the subclass, otherwise a `TypeError` will be raised at runtime. This ensures that all animals can make noise and eat, but also allows for flexibility in how those actions are performed.

ABCs are like the cool kids of programming, helping us write better code by enforcing rules on our classes. And who doesn’t love a good rule-enforcer?

SICORPS