Abstract class and Interface in Python

[Draft]

Abstract Class

Abstract class contains abstract methods and the methods don't contain implementation. All the abstract methods have to implement in their subclasses if not failing Type Error will be raised. ABCMeta module, from abc - abstract base classes, is a metaclass that allows us to define an abstract base class. We will @abstractmethod as a decorator indicating abstract methods.

from abc import ABCMeta, abstractmethod

class Animal(metaclass=ABCMeta):
    @abstractmethod
    def sleep(self):
        pass 
    @abstractmethod
    def eat(self):
        pass 
    @abstractmethod
    def move(self):
        pass 

class Dog(Animal):
    def __init__(self, name, sex, age):
        self.name = name 
        self.sex = sex 
        self.age = age

    def sleep(self):
        print("Dog sleep")
    def eat(self):
        print("Dog eat")
    def move(self):
        print("Dog move")

dog1 = Dog("dog1", "male", 1)
dog1.sleep()

# Output
Dog sleep

An error will throw when the subclass Dog does not define all the methods mentioned in abstract class.

from abc import ABCMeta, abstractmethod

class Animal(metaclass=ABCMeta):
    @abstractmethod
    def sleep(self):
        pass 
    @abstractmethod
    def eat(self):
        pass 
    @abstractmethod
    def move(self):
        pass 

class Dog(Animal):
    def __init__(self, name, sex, age):
        self.name = name 
        self.sex = sex 
        self.age = age

    def sleep(self):
        print("Dog sleep")
    def eat(self):
        print("Dog eat")
    # def move(self):
    #     print("Dog move")

dog1 = Dog("dog1", "male", 1)
dog1.sleep()

# Output 
Traceback (most recent call last):
  File "~/python_oop/abstract_class.py", line 27, in <module>
    dog1 = Dog("dog1", "male", 1)
TypeError: Can't instantiate abstract class Dog with abstract method move

Why do we need an abstract class? The purpose of abstract class is to provide a common definition of a base class. It can be used as a type of template for other classes. The subclasses need to define all the abstract methods which are defined in the abstract class. If not an error will throw.

Interface

Why do we need interfaces? The interface is a blueprint of a class. An interface defines methods, those are called abstract methods because the methods do not implement in the interface, instead, they will be implemented in subclasses. There are two types of interface in python: formal and informal interface. Example 1: Informal interface First, let's create a class with some methods but its methods do not implement.

class Animal:
    def sleep(self):
        pass 
    def eat(self):
        pass 
    def move(self):
        pass

Then we add another class that is inherited from the Animal class and the methods will be overridden.

class Animal:
    ...

class Dog(Animal):
    def sleep(self):
        print("Dog sleep")
    def eat(self):
        print("Dog eat")
    def move(self):
        print("Dog move")

dog1 = Dog()
dog1.sleep()

Although this is a solution of defined interface it also has some drawbacks:

  • There is no clear way to state that Animal class is an interface. In this case, we may rely on the ducking type.

    If it walks like a duck and it quacks like a duck, then it must be a duck

  • The Animal interface still can instantiate like other classes.
  • The subclass can not implement move methods, seem it violates the definition of an interface. Example 2: Formal interface Formal interfaces are suitable for a larger project where many developers work together in a large code base. There are some tools that allow us to implement formal interfaces such as abstract base class module (abc).
from abc import ABCMeta, abstractmethod

class Animal(metaclass=ABCMeta):
    @abstractmethod
    def sleep(self):
        pass 
    @abstractmethod
    def eat(self):
        pass 
    @abstractmethod
    def move(self):
        pass 

class Dog(Animal):
    def sleep(self):
        print("Dog sleep")
    def eat(self):
        print("Dog eat")
    def move(self):
        print("Dog move")

dog1 = Dog()
dog1.sleep()

# Output
Dog sleep

Using abc module will enforce us to override all the abstract methods defined in the interface.

Traceback (most recent call last):
  File "~/python_oop/abstract_class.py", line 22, in <module>
    dog1 = Dog()
TypeError: Can't instantiate abstract class Dog with abstract method move