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