Python Interfaces
We learned that an abstract class is a class which contains some abstract methods as well as concrete methods also. Imagine there is a class that contains only abstract methods and there are no concrete methods. It becomes an interface . This means an interface is an abstract class but it contains only abstract methods. None of the methods in the interface will have body. Only method headers will be written in the interface. So an interface can be defined as a specification of method headers. Since, we write only abstract methods in the interface, there is possibility for providing different implementations (body) for those abstract methods depending on the requirements of objects.In the languages like Java, an interface is created using the key word 'interface' but in Python an interface is created as an abstract class only .
Interfaces
The interface concept is not explicitly available in Python. We have to use abstract classes as interfaces in Python.
Since an interface contains methods without body, it is not possible to create objects to an interface . In this case, we can create sub classes where we can implement all the methods of the interface. Since the sub classes will have all the methods with body, it is possible to create objects to the sub classes. The flexibility lies in the fact that every sub class can provide its own implementation for the abstract methods of the interface.
Interface sub-classes
Let's see how the interface concept is advantageous in software development.A programmer is asked to write a Python program to connect to a database and retrieve the data, process the data and display the results in the form of some reports.For this purpose, the programmer has written a class to connect to Oracle database, something like this:
#this class works with Oracle database only
class Oracle:
def connect(self):
print('Connecting to Oracle database...')
def disconnect(self):
print('Disconnected from Oracle.')
This class has a limitation. It can connect only to Oracle database. If a client (user) using any other database (for example, Sybase database) uses this code to connect to his database, this code will not work. So, the programmer is asked to design his code in such a way that it is used to connect to any database in the world.
In the main program, the programmer is supposed to create objects to the sub classes without knowing their names. This is done using globals() function .
First, the programmer should accept the database name from the user. It may be 'Oracle' or 'Sybase'. This name should be taken in a string, say 'str'. The next step is to convert this string into a class name using the built-in function globals(). The globals() function returns a dictionary containing current global names and globals()[str] returns the name of the class that is in 'str'. Hence, we can get the class name as:
classname = globals()[str]
Now, create an object to this class and call the methods as:
x = classname() #x is object of the class
x.connect()
x.disconnect()
When an interface is created, it is not necessary for the programmer to provide the sub classes for the interface. Any third party vendors can do that. The client or user purchases and uses the interface and the sub class depending on his requirements. If he wants to connect to Oracle, he will purchase Oracle sub class. If he wants to connect to Sybase, he will purchase Sybase sub class.
Interface Example
#An interface to send text to any printer
from abc import * #create an interface
class Printer(ABC):
@abstractmethod
def printit(self, text):
pass
@abstractmethod
def disconnect(self):
pass
class IBM(Printer):
def printit(self, text):
print(text)
def disconnect(self):
print('Printing completed on IBM printer.')
class Epson(Printer):
def printit(self, text):
print(text)
def disconnect(self):
print('Printing completed on Epson printer.')
class UsePrinter:
str = input()
classname = globals()[str]
x = classname()
x.printit('Hello, this is sent to printer')
x.disconnect()