The difference between overloading and overriding in C#

The difference between overloading and overriding in C#

ยท

4 min read

Method overloading and overriding are two common forms of polymorphism ( the ability for a method or class to have multiple forms) in C# that are often confused because of their similar sounding names. In this article, we show the difference between the two with some practical code examples.

Overloading

Overloading is the ability to have multiple methods within the same class with the same name, but with different parameters. Each of these methods has their own implementation as well, meaning that they can behave differently depending on what is passed in.

Overloading is known as compile-time (or static) polymorphism because each of the different overloaded methods is resolved when the application is compiled.

To demonstrate overloading, lets start with a calculator class that doesn't use overloading:

public class Calculator
{
    public int AddTwoInt(int a, int b) => a + b;
    public int AddThreeInt(int a, int b, int c) => a + b +c;
    public double AddTwoDouble(double a, double b) => a + b;
    public double AddThreeDouble(double a, double b, double c) => a + b + c;
}

Here we 4 different methods each with completely different names, each of which performs basically the same the same function, just on different types and amounts of parameters. It's a pretty confusing interface to deal with because you've got to remember the name and parameters for each different method.

Instead, we could refactor this class to use overloading:

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Add(int a, int b, int c) => a + b +c;
    public double Add(double a, double b) => a + b;
    public double Add(double a, double b, double c) => a + b + c;
}

Now all of the methods are just called Add, which is a much simpler interface to deal with as a programmer. We can simply call the Add method with the parameters that we have, and the compiler will automatically work out for us which actual implementation to use!

var calc = new Calculator();

int a = 5;
int b = 6;
// calls int Add(int a, int b)
calc.Add(a, b); 

double c = 4.2
double d = 5.41
double e = 2.57
// calls double Add(double a, double b, double c) 
calc.Add(c, d, e);

Overriding

Overriding, on the other hand, is the ability to redefine the implementation of a method in a class that inherits from a parent class. When a method is overridden, the name and the parameters stay the same, but the implementation that gets called depends on the type of the object that's calling it.

Overriding is known as runtime (or dynamic) polymorphism because the type of the calling object is not known until runtime, and therefore the method implementation that runs is determined at runtime.

As an example, imagine we have a base class called Dog with a Woof method. We mark the method as virtual to signify that this method can be overriden by inheriting classes.

public class Dog
{
    public virtual void Woof()
    {
        Console.WriteLine("Woof!");
    }
}

Currently this and any inherited classes will use the Woof method defined in the Dog class:

public class BigDog : Dog 
{
}

var dog = new Dog();
var bigDog = new BigDog();

dog.Woof() // prints Woof!
bigDog.Woof() // prints Woof!

However, we can choose to override the method so that our inherited classes have a different implementation of Woof:

public class YappyDog : Dog
{
    public override void Woof()
    {
        Console.WriteLine("Woof! Woof! Woof!");
    }
}

var dog = new Dog();
var yappyDog = new YappyDog();

dog.Woof() // prints Woof!
yappyDog.Woof() // prints Woof! Woof! Woof!

Here the base Dog class still uses it's own implementation, but the inherited YappyDog has it's own overridden implementation that it uses. The application checks at runtime what the type of the class is (Dog or YappyDog) and calls the method for that particular type.

Conclusion

Here we have compared two forms of polymorphism in C#, overloading and overriding. We have seen that:

  • Overloading is determined at compile time and is static. Overriding is determined at runtime and is dynamic.
  • Overloading concerns giving a method with the same name different parameters. Overriding concerns defining a different implementation of the same method in inherited classes.

Since it's almost Christmas, you could also check out my Top Christmas Gifts To Buy A Developer post that was featured on Hashnode recently.

I post mostly about full stack .NET and Vue web development. To make sure that you don't miss out on any posts, please follow this blog and subscribe to my newsletter. If you found this post helpful, please like it and share it. You can also find me on Twitter.

Did you find this article valuable?

Support Sam Walpole by becoming a sponsor. Any amount is appreciated!