Mostly questions arise about the difference of overriding and overloading, these are two common terminologies being used widely in Object-oriented programming frameworks and languages. Because most new programmers come from Java or .NET framework, they have to stumble upon many of these Object-oriented programming concepts, among which these two are most confusing ones. In my opinion, the confusion is because of their names. Beginners often confuse themselves with another and cause a confusion that if understood fairly should never come again. In this post, my concern is to explain these concepts in details so that tomorrow when you stumble upon these two things you know which-is-which!
The answer to this question is regularly provided, but since most of the beginners hate to Google for a solution and want to re-start the thread, most of us write the answers in a blog format and then publish the content. The content published is then provided to the OP, which had no interest in searching for a solution. So, that said, this post also has been written by me on separate threads and forums. But re-writing the same thing is pretty much idiotic act and “saving it once use many” will be a good rule to follow. That is why, I am going to write all of the key notes, differences, personal experience in understanding and learning them and other resources. So that someday later when someone asks the same question, I can give him the link to this one single post so that he can learn and I also don’t have to write the same thing again.
What are these-concepts?
Now a days, in application programming, Object-oriented programming model is taken very seriously. Thus giving rise to many concepts, approaches and requirements. In such cases, these new concepts are usually named very tightly as they may require some additional English knowledge base for developers to understand them. I also had these troubles while learning what they actually are, until I tried to Google “define overriding” or like to Google “define overloading”. Google is a great resource for learning, (if you use Bing; you can prefer it) for beginners, I have found many resources and article already published there in a very much simple way which you can read and learn the framework or concepts. Technical documentations by the developers are not easily understood by beginners, that is why third-party or indie developers share their expertise with beginners in a blog-format or an article sharing media. Where they explain:
- What the framework is?
- Why was it needed at all?
- Who built it (optional)?
- Who uses it? (Required and is shared; no one wants to invest their time in learning something that no one uses).
- Am I to use it at any cost?
- How to learn it then?
- Source code compiles, am I there?
These questions are there in every beginner’s mind. They are zealous to learn, thus there comes the fun part where the author has to provide answers to all of these questions that arise in a reader’s mind. If he is not able to explain them, the reader simply consider the framework to be difficult enough.
Same thing here, these are simply concepts, nothing more than that! Each OOP language implements these concepts and provides interfaces and other resources to using these concepts in their application programming models. Nothing else,
Overloading and overriding are just two names of different concepts, they are indeed different and sometimes confused with each other due to their such strange names.
What is overloading?
Overloading, before I conceptualize the use in programming, you should understand the meaning of it first. Native English would get the idea of this term so easily since they use the word in their regular chat, where as for those who are not native, understanding the use requires understanding the word itself.
Definition for “overload” by Google
Thus, the definition provided by Google gives us a very broad and general idea of what this term is. Why would programmers then need it anyway and such other questions arise in our minds. In this section I will be covering those questions also! We are interested in the second definition, “give excessive work, responsibility, or information to.”.
First of all, recall the rules for identifiers, I don’t remember all of them! But there is a rule that an identifier can be used to identify one and only one variable, function or other tokens. So, if you have to write the functions that execute based on values provided or additional cases, you would have to write them with separate names.
- CreateAccount();
- CreateAccountName(string Name);
- CreateAccountFnameSname(string Firstname, string Surname);
- CreateAccountFnameSnameAge(string Firstname, string Surname, int age);
But in OOP, you don’t need to do this. The concept of overloading is that you can define the functions withdifferent signatures. A function will be identified based on the signature that it is being called with.
The signature includes,
- Identifier name.
- Argument list.
Return-type cannot be used for overloading.
Thus, it allows you to write the above code in a much more neater way, like this:
- CreateAccount();
- CreateAccount(string Name);
- CreateAccount(string Firstname, string Surname);
- CreateAccount(string Firstname, string Surname, int age);
Now the rest of the job is assigned to the compiler, it will determine which of these to use and which should be ignored.
-
-
-
- CreateAccount("Afzaal Ahmad Zeeshan");
-
-
-
-
- CreateAccount("Afzaal Ahmad", "Zeeshan");
-
-
-
-
- CreateAccount(customType);
Thus it shortens the code for our need, and we can then use the functions to manage what is to be done in each of these cases. When one argument is provided that is the name, when two are provided they are first and surnames and so on. Plus it allows us to maintain the code-readability, because reading “
CreateAccount(string, string, int)” is simpler than reading “
CreateAccountWithGivenFirstNameSurNameAndAge(string, string, int)”.
Also, I mentioned that you cannot overload a function based on the return type, yes, you cannot.
- class Person {
- int x() { return 0; }
- void x() { }
- }
The above program won’t work. I used a class to ensure they are in same scope, otherwise you will be scratching your head calculating the global and local scopes. Now, the above program complains that there is already a definition for x. I have tried them in both, C++ and C# and both say the same thing in different words.
C++ complains that a function cannot be overloaded based on the return-type. C# complains that there is already a function x defined with
same parameter types. Which ensures that overloading doesn’t care about the return-types, it works with identifier for the function and the parameter types.
Operator overloading
Thinking of overloading, I came to the operator overloading also. The concept of overloading doesn’t just make up the functions overloading, operators can also be overloaded. Operator overloading is somewhat a different concept, you cannot create multiple functions for operators because operators are only applied to 2 items at a time, at max.
- Unary operators
- Binary operators
Unary operators are applied to a single object whereas Binary operators are applied to two objects at a time, in case where there is an expression taking part, the operators work in precedence and resolve the expression by working on 2 objects at a time.
- int result = a + b * c / d;
-
-
-
-
-
-
-
-
-
-
- int result = (a + (b * (c / d)));
You should also consider giving
DMAS rule a quick look, it explains how to resolve the equation to get correct answer!
Operator overloading on the other hand is (but not restrained to be) performed for custom classes and objects. A very common example of such cases and learning techniques is the complex numbers class. Complex numbers have a real and an imaginary part, operator overloading is required to work around with addition, multiplication and other operations. So, for example, you can use a complex number object to work around with your operator overloading skills.
An example here would be to show how to add two Program classes in C#:
- class Program {
- public static string operator + (Program a, Program b) { return "Added"; }
- }
The above program has an
overloaded operator, which returns a string message (see the function signature) “Added” each time you add two Program objects. That is just to show you, that operators also, when overloaded, allow you to perform the functions that you want to! You can return multiple results, such as array of results or you can pass another message, or like talked about complex numbers, you can return another complex number after the operation. In C# overloaded operators are
static, so that is why I provided that keyword in the signature. Rest is the body for the function, where I am only returning a string-literal.
Still got questions?
Well if you still have some questions, I have some answers for them. My apologies if I can still not satisfy your needs.
This is not a TL;DR. 1. Is it really required?
No, it is not required, but is provided as per your need. Whenever you need to overload your functions to allow multiple arguments or different arguments under the same process. You can use (function) overloading. Also, if your objects require arithmetic operations, addition or subtraction, you can overload the operators provided in the language also. Almost every OOP or widely used programming language supports operator overloading.
Note: Java and C do not support operator overloading. Java is an example of OOP language not supporting operator overloading, and C is a widely used programming language that doesn’t support operator overloading.
2. How does it work? (Applies to function overloading)
Overloading is worked out by compiler itself, it makes a choice based on the formal parameters passed to the function. There can be implicit casting that can take place to find a suitable function to handle the call.
Let us compile a few examples and see what happens:
- void func(int i) { }
- void func(char c) { }
- void func(string s) { }
- void func(double d) { }
-
-
- func('c');
- func(5.0);
- func("Hello");
- func(0);
In the above cases, all of the functions are mapped to their representative function calls based on their parameters. First one gets called for the one that accepts a character, then a double (float can be casted to double and so on) and then comes a string later is the integer value. All of these choices were made by the compiler to detect which one to execute;
based on the formal parameters being passed.
Off-record: I am waiting for more questions to be added to the list, if you have one, let me know.
What is overriding?
Just as we noticed a few things about overloading, we should consider learning the same things about overriding also. Let us break the concept into pieces and see what does it have for us and why should we use it anyway. Override, ever heard the same English term in a movie? If you are an Avengers fan of a same military-like movie fan or same, such as Interstellar ( I loved that movie), you must have heard them saying, “override” to some command that machine was talking about. We are talking about the same “
override” function here. Google says,
Definition of “override” by Google
In the above definition-list, we will find our interest in the second definition. “
interrupt the action of (an automatic device), typically in order to take manual control.” Once again, Google has explained the term override and we can understand it in our general-programming concepts. Indeed overriding is used to overcome the default behavior of a function in our objects and APIs. So that we can enforce our own implementations for the process. In the coming sections, I will show you how to override the default behaviors and functions in languages;
C# and C++ are to be taken into concern, Java and others can also be implemented but with a little modification as was in the case of operator overloading.
Object-oriented programming languages provide us with a function
to inherit from base classes. In this post, I won’t share the inheritance concepts, but you should consider giving it a thorough look before moving forward. The inherited functions and other stuff is passed down to the child object, thus allowing it to perform the same functions as the previous one did.
- class Father {
- public void Walk () { }
- }
-
- class Son : Father { }
-
-
Now, we know that we can define functions which can be passed down to the next, as they are generally. The Son object can also walk and so on.
Where is the overloading then? The overloading comes, when Son performs a different action, or overrides the default behavior that was performed for a long time by the base classes; was intended to be performed.
So, for example in a carpenter’s family if father’s job was as a carpenter and somehow son doesn’t like that job and wants to be a football player, he can easily override that and perform his own actions. Like this:
- class Father {
- public virtual string Job () { return "Carpenter"; }
- }
-
- class Son : Father {
-
- public override string Job () { return "Footballer"; }
- }
In the above code, there were two tag marks added. One of them to the father and other to the son. The tag mark of “virtual” meant, that this can be overriden. So Father object does allow the derived objects to perform a different action, and child if interested in, can perform a different action or can maintain the family occupation and serve as a carpenter. The keyword “virtual” (or “abstract”; explained later) is required in order to override the default behavior in derived objects. It is just to change the implementation of a procedure.
Question and answer session: - What are virtual and abstract keywords?
These keywords are used to identify the functions that can be overridden. Abstract is somewhat a different story and it takes you back to the inheritance and the concept about concrete and abstract classes and etc. I am not interested in confusing you for those topics here.
Long story short, virtual is applied to the functions, that can be overridden.
- Any real world implementation?
Yes, if you are a C# programmer you would have noticed (and known) that object is the base class for every managed type. In a C# program, when you call the .ToString function (where does that come from? See the first code sample in this overriding section) the program itself returns the full type name for it. For example,
- using System;
-
- namespace Example {
- class Program {
- static void Main(string[] args) {
-
- Console.WriteLine(
- new Program()
- );
- }
- }
- }
-
-
-
Which is the type name for the class object. Now, for example if you have a class that holds the data for the users. You don’t have to create a separate function to display the details for a user, you can override the function and change its implementation for your class.
- class User {
- public string Name { get; set; }
- public int Age { get; set; }
-
- public override string ToString() {
- return string.Format("Name: {0}, Age: {1}", this.Name, this.Age);
- }
- }
The above code, when called as:
- var user = new User
- {
- Name = "Afzaal Ahmad Zeeshan",
- Age = 20
- };
-
- Console.WriteLine(user);
Would provide you with the following output:
Name: Afzaal Ahmad Zeeshan, Age: 20
Pretty easy isn’t it? We have no overridden the default behavior of object’s ToString function. You can in a similar manner, override other functions and procedures as required.
Points of Interest
This post would be much beneficial to those who don’t understand the concept of overloading and overriding and their common difference. This post aims at them, to teach them the difference. I hope by now you must have understand the common difference of them.
If you still get confused over something, or you have another question for them, do let me know and I will update the post for future readers. Finally, a graphical difference of overloading and overriding is:
Illustration of the difference.