Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#5.0

Still Don’t Get the Difference of “Overloading and Overriding”?

5.00/5 (20 votes)
4 Sep 2015CPOL15 min read 34.3K  
This post attempts to describe the general difference between overloading and overriding in Object-oriented programming languages.

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 the 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 a pretty much idiotic act and “saving it once use many times” 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 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 articles already published there in a very much simple way which you can read and learn the framework or concepts. Technical documentation 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:

  1. What the framework is?
  2. Why was it needed at all?
  3. Who built it (optional)?
  4. Who uses it? (Required and is shared; no one wants to invest their time in learning something that no one uses)
  5. Am I to use it at any cost?
  6. How to learn it then?
  7. 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, whereas for those who are not native, understanding the use requires understanding the word itself.

Definition for "overload" by Google.

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.

C#
CreateAccount(); // No arguments
CreateAccountName(string Name); // Full name argument
CreateAccountFnameSname(string Firstname, string Surname); // Both parts provided
CreateAccountFnameSnameAge(string Firstname, string Surname, int age); // Other details

But in OOP, you don’t need to do this. The concept of overloading is that you can define the functions with different signatures. A function will be identified based on the signature that it is being called with. The signature includes:

  1. Identifier name
  2. 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:

C#
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.

C#
/*
 * This function would trigger the second function, 
 * because I am passing only one string argument to it: CreateAccount(string);
 */
CreateAccount("Afzaal Ahmad Zeeshan");

/*
 * This would then trigger the third function, 
 * as I have provided it with 2 string arguments: CreateAccount(string, string);
 */
CreateAccount("Afzaal Ahmad", "Zeeshan");

/* 
 * No overload found for CreateAccount(type);
 */
CreateAccount(customType); // Assume customType is an instance of CustomType class

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.

C#
class Person {
   int x() { return 0; }
   void x() { }
}// here comes ; in case of C++ program

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 as well. 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.

  1. Unary operators
  2. Binary operators

Unary operators are applied to a single object whereas Binary operators are applied to two objects at a time, in case there is an expression taking part, the operators work in precedence and resolve the expression by working on 2 objects at a time.

C#
int result = a + b * c / d;

/*
 * In the above expression:
 *   1. First of all c is divided by d; DivideByZero to be taken care of. 
 *   2. Then the result of (c / d) is multiplied with b.
 *   3. Finally the result of (b * (c / d)) is added to a.
 *   4. Their sum is then resolved as a value for variable "result".
 *
 * So the final expression that is resolved is as:
 */ 
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 the 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 show how to add two Program classes in C#:

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 the 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:

C#
void func(int i) { }
void func(char c) { }
void func(string s) { }
void func(double d) { }

// Call them
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 cast 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.

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.

C#
class Father {
   public void Walk () { /* Walk some meters */ }
}

class Son : Father { }

// new Son().Walk(); would be OK!

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,:

C#
class Father {
   public virtual string Job () { return "Carpenter"; }
}

class Son : Father {
   // Override
   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 overridden. 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

1. 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, 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.

2. 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:

C#
using System;

namespace Example {
   class Program {
      static void Main(string[] args) {
         // Our very basic Console app.
         Console.WriteLine(
           new Program()
         );
      }
   }
}

// Output:
// Example.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.

C#
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...

C#
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 not overridden the default behavior of object’s ToString function. You can in a similar manner, override other functions and procedures as required.

3. What If I Do Not Override the Functions?

Now what actually happens in case I do not override the function? In that case, the default (inherited) function is executed. That is the default behavior of inheritance. So for example what Father object did would be done by Son object also, no difference.

C#
class Father 
{ 
   public virtual void SayHello() { Console.WriteLine("Hello world!"); }
}

class Son : Father { }

Once we use the above code and try out the Son object's function, it would execute the same one that is provided in the Father object.

C#
new Son().SayHello(); // Hello world!

Thus, in most cases, for example when you create a new class. We do not override the following functions:

  1. Equals
  2. GetHashCode
  3. ToString

These functions are provided to each class to get some extra features, read their documentation for more information. You can override them, but if you do not, they do their job. Equals returns whether an object equals to another object, GetHashCode returns the hash code for that object, used in HashTable for example. ToString returns the string representation for the class; full type name. Remember, it is entirely legal to ignore overriding the functions.

4. What is the difference between override and new keyword usage in overriding?

Quite an interesting question that would help many readers and beginners in understanding what happens underground when you override a function of base class. In overriding, you can override the functions that are marked virtual (not going to talk about abstract, that needs to understand some body-less functions and declaring the class to be abstract, and much more... I will cover it in a separate post), otherwise you cannot override the function.

C#
public class Father 
{
   public virtual void Overridable() { Console.WriteLine("Instance of Father."); }
   public void DoNotOverride() { }
}

public class Son : Father 
{
   public override void Overridable() { Console.WriteLine("Instance of Son."); }
   public override void DoNotOverride() { } // Cannot override, not marked as "virtual" or "abstract"
}

The above comment in the final line of code is an excerpt of what compiler would actually show as a compile-time error. The actual error has something like, "Son.DoNotOverride cannot override inherited member Father.DoNotOverride because it is not marked as virtual or abstract or override". (The last item comes because everything inherits from System.Object, so give inheritance in C# a quick look). Then the idea is pretty much clear, no need for further digging.

Now the main purpose of this answer is to clarify the purpose and difference of override and new keyword. First of all, you already know the purpose of override (see the above code block in the same question). It simply just overrides the default behavior, now let us talk about the new keyword in overriding.

C#
class Father 
{
   public virtual void SayHello() { Console.WriteLine("Hello!"); } 
}

class Son : Father
{
   public new void SayHello() { Console.WriteLine("New Hello!"); }
}

Now once the above code is executed, what happens is this:

C#
new Son().SayHello(); // New Hello!

Wait, that is same as what override did, isn't it? Well, yes, in case of output but in case of logic they are different. new keyword hides the inherited function at all. It hides the previous implementation and creates a new function in the derived class.

C#
// That is why
Father boxedSon = new Son();
Son son = new Son(); 

boxedSon.SayHello(); // Hello!
son.SayHello();      // New Hello!

Actually, the new operator is used to overcome the warning generated by compiler that claims that you must either add override or new to the function signature because the function hides the inherited member.

C#
class Father 
{
   public virtual void SayHello() { }
}

class Son : Father 
{
   public void SayHello() { } // Warning here!
}

To overcome the warning, you should consider either adding a new or override keyword. But remember, that new keyword works with those functions which do not have virtual applied to them (not talking about abstract).

So, here is the short term answer. Override is used to override the virtual or abstract functions in a base class. Whereas new keyword is used to hide the inherited functions (no matter if they were virtual or not!) and is used to create a new implementation of the function.

C#
class Father
{
   public void DoNotOverride() { }
}

class Son : Father
{
   public new void DoNotOverride() { Console.WriteLine("Didn't mention the new operator."); }
}

The above program is entirely legal and once you use the code, it would print out the function from the derived class, with that string in it.

C#
new Son().DoNotOverride(); // Didn't mention the new operator.

So, that is the main difference between override and new. Got a bit lengthy didn't it?

Points of Interest

This post would be very beneficial to those who don’t understand the concept of overloading and overriding and their common difference. This post is targeted at them to teach them the difference. I hope by now you must have understood 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.

Illustration of the difference

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)