Operator overloading and function overloading are terms that we commonly encounter in computer programming. While they are often associated with polymorphism, it’s crucial to specify that they are instances of compile-time (or static) polymorphism.
If you’re not familiar with the concept, polymorphism is an object-oriented programming principle where objects from different classes can respond to the same message, but in different ways. Essentially, polymorphism allows using the same operator or function and provides various outcomes, depending on the context.
It’s also important to differentiate between compile-time polymorphism (like operator and function overloading) and run-time polymorphism (like method overriding). Compile-time polymorphism is determined at the time of compilation, while run-time polymorphism is resolved during the execution of the program.
I’ve written an in-depth guide about object-oriented programming (OOP) in Python. If you lack the basic knowledge of OOP, you check out that article here.
Now let’s look at the difference between operator overloading and function overloading.
Operator overloading enables operators to extend their predefined operational meaning based on their operands’ data types or classes. On the other hand, function overloading, also known as method overloading, allows us to define multiple methods with the same name but with different parameter lists in the same scope.
When we call an overloaded declaration, the compiler finds out the exactly appropriate function to use, based on the argument types you have used in the function call. The process of selecting the suitable overloaded function or operator is called overload resolution. This is how overloading works in most programming languages.
Now let’s dive deep into both these concepts to learn more about them. Let’s start with operator overloading.
Operator overloading is a programming concept where different operators have different implementations depending on their arguments. It is the mechanism of giving a special meaning to an operator. Operator overloading allows operators to have an extended meaning beyond their predefined operational meaning.
We can overload all existing operators in a programming language, but we can’t create a new operator.
Note: Operator overloading is typically done in Python and other object-oriented languages like C++, where operators can be overloaded by defining a specific method in the class definition.
Python provides some special functions called magic functions for each operator that is automatically invoked when it is associated with that particular operator. For example, if we are overloading the “+” operator, the magic method __add__ is automatically invoked in which the functionalities of the + operator are defined.
For example, we can add two integer values using the + operator. We can also add two string values as well. But, we can’t use the + operator to add an integer with a string. If we do so, Python’s interpreter will raise a TypeError during program execution because it doesn’t know how to add two different types of objects. However, we can define a method for this operator and then use it.
To define an additional task to an operator, we must specify what it means to the class to which the operator is applied. We can do it with the help of defining a special function, which is called the operator function.
You can define operator methods in your class, and operators work according to that behavior defined in methods.
In Python, operator functions are the same as normal functions. But in some other languages, there are some differences in the syntax.
Enough of the theory, let’s see some Python code to understand everything.
Let’s say we have an integer value and a string value.
a = 3 b = 'apples'
We want to add these two variables together. But, when we use the + operator, it will cause an error.
TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
So, we need to define an operator function for +.
class Apple: def __init__(self,x): self.x = str(x) def __add__(self,y): return self.x + y.x obj1 = Apple(3) obj2 = Apple('apples') print(obj1+obj2)
Here in this example, we defined a special function by converting the integer value to string within the function. Now, when we run this code, we will not get the error. Instead, we will get the concatenated values as the output.
In the above example, the output will be:
In this way, we can give a special definition to almost all the operators (except a few) in Python.
As we have seen, overloading means the use of the same thing for different purposes. In function overloading, we can define two or more functions with the same name and in the same scope.
We can define a family of functions with one function name but with different argument lists. The function would perform different operations depending on the argument list in the function call. This feature is commonly known as method overloading, because we call functions as methods in object-oriented programming.
You can define a method in such a way that there are multiple ways to call it. Depending on the function definition, it can be called with zero, one, two, or more parameters.
The overloaded member functions could be invoked by matching arguments, specifically, the number of arguments and their data types.
In Python, we use a different approach for function overloading. Since Python does not support function overloading in the traditional sense, we can achieve similar functionality using default arguments, variable-length arguments, or dispatch methods.
Let’s see an example Python program to understand the concepts of method overloading.
class Greetings: def Hello(self, name=None): if name is not None: print('Hi ' + name) else: print('Hi') obj = Greetings() obj.Hello() obj.Hello('Ashwin')
As you can see in this example, the same function Hello() is used for different purposes. The first parameter of this method is set to None. So, we can call it with or without an argument.
Since we can’t create multiple functions with the same name in Python, we used the default parameter as None.
If we call the function with or without an argument, the compiler can distinguish what was intended to be used at each occurrence.
Sometimes, people often get confused with method overloading and method overriding. The latter is a completely different feature in polymorphism.
Overloading occurs when multiple methods in one class have the same name but different parameters. Overriding occurs when a subclass provides a different implementation for a method that is already defined in its parent class, having the same method name and parameters.
In this article, we have seen the basic concepts of operator overloading and function overloading along with example Python programs. If you have any doubts regarding the concepts that we have discussed, feel free to put your comments down below. I’ll be happy to help you.
I hope you got a clear idea about operator overloading and function overloading. Check out this article to further explore the concept of polymorphism in Python.