Do you like coffee?
I think you do. So how we make coffee?
- Pour milk into the container
- Mix coffee and sugar
- Drink the coffee
Wouldn't it be easier if someone else can make it for us? So let us buy an espresso machine and by pushing a button, we get our coffee. But how we are getting the coffee by pushing the button, we do not care because we are getting our coffee. The same happens in programming if there are steps we need to repeat multiple times then we create a function for that.
However, Just like an espresso machine, we want users to have information about what the object does instead of how it does it. For this to happen we have a concept of Abstraction in Python.
Abstraction is hiding the implementation and only showing the features we want.
An abstract class is a class having an abstract method. An abstract method is just like any other method but it is just declared in that class without any body. For example,
def any_abstract_method():
pass
It's body is defined differently for the different subclasses extending the abstract class.
So, we create common methods for subclasses and their implementation is different for different subclasses that means the user is unaware of the basic implementation of the function property.
Let us consider espresso machines as an abstract class because we do not know what is happening inside and our make_coffee
is an abstract method, but for make_coffee
method (to make coffee) everyone will use different ingredients like Nescafé, Lavazza, caribou coffee, etc.
Thus, if we have an abstract method then it will only have the method signatures it will not have anybody. Simply you could say it would have the parameters but no implementation.
We can't create an object of the abstract class but can do it for the subclass.
How to Implement Abstraction in Python
- Python3
from abc import ABC, abstractmethod
class Fees(ABC):
def print_slip(self,amount):
print("Fees submitted : ",amount)
@abstractmethod
def fees(self,amount):
pass
class Class10(Fees):
def fees(self,amount):
print("Total Fees of Class 10th: ",amount)
class Class12(Fees):
def fees(self,amount):
print("Total Fees of Class 12th:",amount)
obj = Class10()
obj.fees(20000)
obj.print_slip(20000)
obj = Class12()
obj.fees(50000)
obj.print_slip(50000)
- Python3
from abc import ABC , abstractmethod
ABC
and abstractmethod
from the module abc
.Keep in mind that ABC and abc are different. If you interchange both you will get syntax errors.
syntax : Class SubClassname(SuperClassname)
- Python3
class Fees(ABC):
def print_slip(self, amount):
print("Fees submitted : ",amount)
@abstractmethod
def fees(self,amount):
pass
In class Fees, we have created two functions one is a normal function and the other is an abstract method. For the abstract method, the subclasses of Fees will have their own functionalities.
So to try our concept, we create two different subclasses of the Fees class to have their own functionalities for the abstract method.
- Python3
class Class10(Fees):
def fees(self, amount):
print("Total Fees of Class 10th: ",amount)
class Class12(Fees):
def fees(self,amount):
print("Total Fees of Class 12th:",amount)
Here we have created two subclasses Class10 and Class12. Both the classes have fees methods but with their own functionality.
So let us check what happens if we create objects of both classes and call the fees method as well as what happens if we call the normal function (print_slip
) from the object of the subclasses.
- Python3
obj = Class10()
obj.fees(20000)
obj.print_slip(20000)
obj = Class12()
obj.fees(50000)
obj.print_slip(50000)
Output:
What is a Static Method?
Static methods are those that you can call without creating an object of the class. You use a static method when you do not want to use class variables.
What if you want to make your abstract method as Static?
It's easy when you want to combine two decorators. You mention the decorators here we want to combine static and abstract together. So we will write it like this.
- Python3
from abc import ABC, abstractmethod
class Fees(ABC):
def print_slip(self, amount):
print("Fees submitted : ",amount)
@staticmethod
@abstractmethod
def fees(amount):
pass
class Class10(Fees):
@staticmethod
def fees(amount):
print("Total Fees of Class 10th: ",amount)
class Class12(Fees):
@staticmethod
def fees(amount):
print("Total Fees of Class 12th:",amount)
Class10.fees(2000)
Class12.fees(2000)
Output:
@abstractmethod comes last in the row when you write a combination of decorators otherwise it will give error.
However, there is another way where we can combine the decorators together in a single line or write it as a single decorator example @abstractstaticmethod
, @abstractclassmethod
, @abstractproperty
, etc.
- Python3
from abc import ABC, abstractstaticmethod
class Fees(ABC):
def print_slip(self, amount):
print("Fees submitted : ",amount)
@abstractstaticmethod
def fees(amount):
pass
class Class10(Fees):
@staticmethod
def fees(amount):
print("Total Fees of Class 10th: ",amount)
class Class12(Fees):
@staticmethod
def fees(amount):
print("Total Fees of Class 12th:",amount)
Class10.fees(2000)
Class12.fees(2000)
We made a simple change instead of writing two decorators we wrote it as a single decorator (@abstractstaticmethod).
Remember when you create an abstract static method then in the subclass, you define the method as static.
You might have noticed that we have removed the self-parameter as well because of that without creating the instance of the class, we can call the method.
Output:
Remember : @abstractstaticmethod,@abstractclassmethod and @abstractproperty decorators have been deprecated since python3.3 so you should not use them. Instead of these you can use the combination of decorators as we have seen above.
What is class method?
The class method does need any instance it works on the class scope. As in normal methods, we pass the instance as the first argument but in the class method, we pass the class as the first argument. Class methods can also change the state of the class.
We can also combine abstract method and class methods by mentioning it as @abstractclassmethod.
- Python3
from abc import ABC, abstractclassmethod
class Fees(ABC):
def print_slip(self,amount):
print("Fees submitted : ",amount)
@abstractclassmethod
def Fees(cls,amount):
pass
class Class10(Fees):
@classmethod
def fees(cls,amount):
print("Total Fees of Class 10th: ",amount)
class Class12(Fees):
@classmethod
def fees(cls,amount):
print("Total Fees of Class 12th:",amount)
Class10.fees(2000)
Class12.fees(2000)
Output:
What is @property decorator?
The property decorator makes the method access as an attribute rather than calling it with “()” .
We can use both the @abstractmethod
and @property
together by using @abstractproperty
- Python3
from abc import ABC, abstractproperty
class Fees(ABC):
@abstractproperty
def classname(self):
pass
class Class10(Fees):
@property
def classname(self):
print("I am in class 10")
print(Class10.classname)
Class10().classname
Output