Skip to main content

Abstract Classes

Abstract Classes in Python

In object-oriented programming, an abstract class is a class that cannot be instantiated and is designed to be subclass, providing a basic interface for its derived classes. Python is an object-oriented language that supports abstract classes through its Abstract Base Class (ABC) module. This module provides a way to define abstract classes and enforce their interface on their subclasses. This article will explore the concept of abstract classes in Python and how they are implemented using Python abstract base class.

Introduction to Python Abstract Class

In Python, an abstract class is a class that is designed to be inherited by other classes. It cannot be instantiated on its own and its purpose is to provide a template for other classes to build on.

An abstract base class in Python is defined using the abc module. It allows us to specify that a class must implement specific methods, but it doesn't provide an implementation for those methods. Any class that inherits from an abstract base class must implement all the abstract methods.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

r = Rectangle(5, 6)
print(r.area())    ### Output 30

In the above example, Shape is an abstract base class that defines an abstract method area. Rectangle is a concrete class that inherits from Shape and implements the area method.

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def talk(self):
        pass

class Dog(Animal):
    def talk(self):
        return "Woof!"

class Cat(Animal):
    def talk(self):
        return "Meow"

c = Cat()
print(c.talk())    ### Output Meow

d = Dog()
print(d.talk())    ### Output Woof!

In this example, Animal is an abstract base class that defines an abstract method talk. Dog and Cat are concrete classes that inherit from Animal and implement the talk method.

In conclusion, abstract classes in Python provide a way to define a template for other classes to build on. They cannot be instantiated on their own and they provide a way to ensure that subclasses implement specific methods. The abc module provides a way to define abstract base classes in Python.

Creating Python Abstract Base Class

An abstract class is a class that cannot be instantiated and is meant to be used as a base class for other classes.

In Python, the abc module provides ABC class. It is used to create abstract base classes.

To create an abstract base class, we need to inherit from ABC class and use the @abstractmethod decorator to declare abstract methods.

Example of Abstract Class

from abc import ABC, abstractmethod

class Shape(ABC):

    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

In this example, we have created an abstract base class Shape with two abstract methods area and perimeter. Any class that inherits from Shape has to implement these two methods.

Example of Abstract Class with Inheritance


from abc import ABC, abstractmethod

class Animal(ABC):

    @abstractmethod
    def sound(self):
        pass

class Dog(Animal):

    def sound(self):
        return 'Woof'

In this example, we have created an abstract base class Animal with an abstract method sound. We have also created a class Dog that inherits from Animal and implements the sound method.

A class that inherits from an abstract base class must implement all the abstract methods declared in the base class, unless it is also an abstract class.

Python Abstract Class vs Interface

An abstract class is a Python class that cannot be instantiated, and it is used to define common properties and behaviors that subclasses can inherit. It is defined using the abc module, which stands for abstract base class. An abstract class is used when we want to define a base class, and we don't want it to be instantiated. Instead, we want it to be subclassed by other classes that will provide specific implementations of its abstract methods.

Example of a Python Abstract Base Class

from abc import ABC, abstractmethod
 
class Animal(ABC):
     
    @abstractmethod
    def move(self):
        pass
 
class Dog(Animal):
     
    def move(self):
        print("I am walking on four legs")
         
class Snake(Animal):
     
    def move(self):
        print("I am slithering")
         
d = Dog()
d.move()
 
s = Snake()
s.move()

In the above example, Animal is an abstract base class with an abstract method called move(). Dog and Snake are two subclasses of the Animal class, and they provide their specific implementations of the move() method.

Interfaces in Python

An interface is a collection of abstract methods that defines the behavior of a class. In Python, there is no strict definition of an interface like in other programming languages like Java. Instead, we use abstract classes to define interfaces. An interface can be considered as a contract between the class and the outside world. A class that implements an interface must provide an implementation for all the methods defined in the interface.

Example of a Python Interface

from abc import ABC, abstractmethod
 
class Shape(ABC):
     
    @abstractmethod
    def area(self):
        pass
 
    @abstractmethod
    def perimeter(self):
        pass
 
class Rectangle(Shape):
     
    def __init__(self, length, width):
        self.length = length
        self.width = width
     
    def area(self):
        return self.length * self.width
     
    def perimeter(self):
        return 2 * (self.length + self.width)

r = Rectangle(10, 5)
print("Area of Rectangle:", r.area())  # Area of Rectangle: 50
print("Perimeter of Rectangle:", r.perimeter()) # Perimeter of Rectangle: 30

In the above example, Shape is an interface with two abstract methods called area() and perimeter(). Rectangle is a class that implements the Shape interface and provides its implementation for the area() and perimeter() methods.

Polymorphism in Python Abstract Classes

An abstract class is a class that cannot be instantiated, but it can be used as a base for other classes. It is a way to define a common interface for a group of related classes. Polymorphism is the ability of an object to take on many forms. In Python, abstract classes can be used to implement polymorphism.

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def move(self):
        pass

class Dog(Animal):
    def move(self):
        print("Dog is running")

class Cat(Animal):
    def move(self):
        print("Cat is jumping")

d = Dog()
c = Cat()

d.move() ### This will print "dog is running"
c.move() ### This will print "cat is jumping"

Usage of Python Abstract Base Classes

Abstract classes in Python are classes that cannot be instantiated, and are meant to be inherited by other classes. They are useful for defining common methods and properties that should be implemented by their concrete subclasses.

One way to implement abstract classes in Python is to use abstract base classes (ABCs) from the abc module. An ABC is a special type of class that cannot be instantiated directly, but can be subclassed. ABCs define one or more abstract methods, which are methods that must be implemented by any concrete subclass.

The following code example shows how to define an abstract base class Animal, which defines two abstract methods speak and move that must be implemented by any concrete subclass:

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass
    
    @abstractmethod
    def move(self):
        pass

class Cat(Animal):
    def speak(self):
        print('meow')
    
    def move(self):
        print('running')

Now, any concrete subclass of Animal must implement both speak and move.

Another benefit of using ABCs in Python is that they can be used to enforce certain interface contract on classes, without specifying their implementation details.

For example, if you want to define a function that accepts only objects that have a draw method, you could define an ABC called Drawable, which defines an abstract method draw:

from abc import ABC, abstractmethod

class Drawable(ABC):
    @abstractmethod
    def draw(self):
        pass
        
def draw_all(drawables):
    for drawable in drawables:
        drawable.draw()

class Rectangle(Drawable):
    def draw(self):
        print('Drawing a rectangle')
    
    
class Circle(Drawable):
    def draw(self):
        print('Drawing a circle')
    
draw_all([Rectangle(), Circle()])

In this example, the draw_all function accepts a list of Drawable objects, which it draws by calling their draw method. The Rectangle and Circle classes both implement the draw method, so they can be used with draw_all function.

Overall, abstract base classes in Python provide a powerful tool for code design, by allowing you to define common functionality that can be easily extended and customized by concrete subclasses.

Best Practices for Designing Python Abstract Classes

When designing abstract classes in Python, it is important to follow best practices to ensure a maintainable and readable codebase.

  1. Use the abc module to define an abstract base class (ABC).
import abc

class Shape(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def area(self):
        pass
    
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
        
    def area(self):
        return 3.14 * self.radius ** 2
  1. Use abstract methods to specify the contract that derived classes must follow.
import abc

class Vehicle(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def start_engine(self):
        pass
    
class Car(Vehicle):
    def start_engine(self):
        print("Engine started")

class Bike(Vehicle):
    pass

my_car = Car()
my_car.start_engine()    # "Engine started"

# my_bike = Bike()    TypeError: Can't instantiate abstract class Bike with abstract methods start_engine

Following these best practices will ensure that your abstract classes are easily understandable and maintainable, with clear contracts for derived classes to follow.

Contribute with us!

Do not hesitate to contribute to Python tutorials on GitHub: create a fork, update content and issue a pull request.

Profile picture for user AliaksandrSumich
Python engineer, expert in third-party web services integration.
Updated: 09/24/2023 - 10:14