Abstract Classes in Python (51/100 Days of Python)

Martin Mirakyan
5 min readFeb 21, 2023

--

Day 51 of the “100 Days of Python” blog post series covering abstract classes

One of the fundamental concepts of object-oriented programming is the concept of abstraction. Abstraction is the process of hiding unnecessary implementation details and exposing only what is essential to the user. Abstract classes are a way to implement abstraction in Python. In this blog post, we will explore what abstract classes are, how they work, and how to use them with real-world examples.

What are Abstract Classes in Python?

An abstract class is a class that cannot be instantiated, meaning that we cannot create an object of the abstract class. Instead, we can only create objects of its derived classes. An abstract class can have abstract methods, which are methods without implementation. These methods are meant to be implemented by the derived classes, and they provide a common interface for all derived classes. The derived classes are required to implement all the abstract methods of the abstract class, or else they too will be considered abstract classes. We can create an abstract class using the abc built-in library:

from abc import ABC, abstractmethod


class MyClass(ABC):
@abstractmethod
def some_method(self):
pass

In this code, we import the ABC and abstractmethod modules from the abc module, which stands for Abstract Base Classes. We create a class called MyClass that inherits from ABC, and we decorate the some_method with the @abstractmethod decorator. This tells Python that some_method is an abstract method that needs to be implemented by the derived classes.

If we try to create an instance of the defined class, we’ll get a TypeError:

obj = MyClass()
# TypeError: Can't instantiate abstract class MyClass with abstract method some_method

Using Abstract Classes to Represent Shapes

Suppose we want to create a program that calculates the area and perimeter of various shapes, such as rectangles, squares, and circles. We can create an abstract class called Shape that defines the common interface for all shapes, and then create derived classes for each specific shape.

from abc import ABC, abstractmethod
from math import pi


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

@abstractmethod
def perimeter(self):
pass


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

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

def perimeter(self):
return 2 * (self.width + self.height)


class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return pi * self.radius ** 2

def perimeter(self):
return 2 * pi * self.radius

In this code, we create an abstract class called Shape that defines the area() and perimeter() methods, which are meant to be implemented by the derived classes. We then create two derived classes: Rectangle and Circle. The Rectangle class has its own implementation of the area() and perimeter() methods, while the Circle class has its own implementation of these methods as well:

from abc import ABC, abstractmethod
from math import pi


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

@abstractmethod
def perimeter(self):
pass


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

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

def perimeter(self):
return 2 * (self.width + self.height)


class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return pi * self.radius ** 2

def perimeter(self):
return 2 * pi * self.radius


# Show examples how to use the classes above
rectangle = Rectangle(3, 4) # 3 is the width, 4 is the height
print(rectangle.area()) # 12
print(rectangle.perimeter()) # 14

circle = Circle(3) # 3 is the radius
print(circle.area()) # 28.274333882308138
print(circle.perimeter()) # 18.84955592153876

# Demonstration that you cannot instantiate an abstract class
shape = Shape()
# TypeError: Can't instantiate abstract class Shape with abstract methods area, perimeter

In this code, we first import the ABC and abstractmethod modules from the abc module. These modules provide the functionality to create abstract classes and abstract methods in Python.

We then create an abstract class called Shape that inherits from ABC. Shape defines two abstract methods, area() and perimeter(), which are meant to be implemented by the derived classes. We then create two derived classes, Rectangle and Circle, which both inherit from Shape. Each derived class has its own implementation of the area() and perimeter() methods. This makes sure that we can use any derived class of Shape similarly. So, all of them will have a correctly implemented method called area and permieter.

Working With Different Animals Using Abstract Classes

Suppose we want to create a program that models different types of animals, such as dogs, cats, and birds. We can create an abstract class called Animal that defines the common interface for all animals, and then create derived classes for each specific animal:

from abc import ABC, abstractmethod


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


class Dog(Animal):
def speak(self):
return 'Woof!'


class Cat(Animal):
def speak(self):
return 'Meow!'


class Bird(Animal):
def speak(self):
return 'Tweet!'


dog = Dog() # Create an instance of the Dog class
cat = Cat() # Create an instance of the Cat class
bird = Bird() # Create an instance of the Bird class

print(dog.speak()) # Woof!
print(cat.speak()) # Meow!
print(bird.speak()) # Tweet!

7 Things to Know About Abstract Classes in Python

  1. Abstract classes cannot be instantiated: This means that you cannot create an object of an abstract class. Abstract classes are meant to be used as a blueprint for creating derived classes, which will have their own implementation of the abstract methods.
  2. All abstract methods must be implemented by derived classes: If a derived class does not implement all the abstract methods defined in the abstract class, it will also be considered an abstract class, and cannot be instantiated.
  3. Abstract classes can have concrete methods: In addition to defining abstract methods, abstract classes can also have concrete (i.e., non-abstract) methods. These methods can be used by both the abstract class and its derived classes.
  4. Abstract classes can have class methods and static methods: Like regular classes, abstract classes can also have class methods and static methods. Class methods are methods that operate on the class itself, while static methods are methods that do not depend on the class or instance.
  5. Abstract classes can be used to enforce a common interface: By defining abstract methods in an abstract class, we can enforce a common interface for all derived classes. This can make our code more organized, readable, and maintainable.
  6. Abstract classes are part of the ABCs (Abstract Base Classes) module: The abc module provides the ABC and abstractmethod classes that are used to create abstract classes and abstract methods in Python.
  7. Abstract classes are not the only way to implement abstraction in Python: Python also supports other forms of abstraction, such as interfaces (using the abc.ABCMeta metaclass) and mixins (using multiple inheritance).

What’s next?

--

--