Introduction


Method Overloading is a feature that allows a class to have more than one method with the same name, provided their parameter lists (signatures) are different. It is the primary form of Static Polymorphism (also known as Compile-Time Polymorphism).

Why “Static”? It is called “Static” because the Compiler performs the heavy lifting. When you write a line of code calling an overloaded method, the compiler inspects the arguments you provided and “binds” that call to the specific memory address of the correct version of the method. This happens during the Build process, not while the game or app is running.

Local Overloading (inter-class)

Local overloading occurs when multiple versions of a method exist within the same class. This is used to provide flexibility for the user of the class.

public class Logger
{
    // Version 1: Standard output
    public void Write(string message) 
    {
        Console.WriteLine("LOG: " + message);
    }

    // Version 2: Output with a severity level (Overloaded by Number)
    public void Write(string message, int level) 
    {
        Console.WriteLine($"LEVEL {level} LOG: {message}");
    }

    // Version 3: Output with a timestamp (Overloaded by Type/Order)
    public void Write(DateTime time, string message) 
    {
        Console.WriteLine($"[{time}]: {message}");
    }
}

Overloading via Inheritance ( Inter-Class)


This is a more advanced concept where a Derived (Child) Class introduces a new version of a method that it has inherited from a Base (Parent) Class.

The Mechanical Reality When a Child class inherits from a Parent, it “copies” all the Parent’s methods into its own scope. If the Child then defines a method with the same name but different parameters, it has successfully overloaded that method across the inheritance hierarchy.

Simple Example

// Parent Class
class ClassA
{
    // Version 1: Adds two whole numbers
    public void Add(int x, int y)
    {
        Console.WriteLine("Class A Result: " + (x + y));
    }
}

// Child Class
class ClassB : ClassA
{
    // Version 2: OVERLOADED method
    // Same name (Add), but takes THREE numbers instead of two
    public void Add(int x, int y, int z)
    {
        Console.WriteLine("Class B Result: " + (x + y + z));
    }
}
ClassB obj = new ClassB();

// Scenario 1: Providing 2 inputs
// The computer looks at Class B, doesn't find a 2-input version, 
// so it looks up to Class A and runs Version 1.
obj.Add(5, 10); 

// Scenario 2: Providing 3 inputs
// The computer looks at Class B and finds the 3-input version.
// It runs Version 2 immediately.
obj.Add(5, 10, 15);
// making a return from this one.


// Version 1: Adds two whole numbers
public int Add(int x, int y)
{
	Console.WriteLine("Class A Result: " + (x + y));
	return x + y;
}

public int Add(int x, int y, int z)
{
	Console.WriteLine("Class B Result: " + (x + y + z));
	return x + y + z;
}

The Technical Constraints (The “Must-Knows”)

I. The Return Type Restriction

A common mistake for beginners is trying to overload by changing the Return Type (e.g., changing void to int).

  • Why it fails: The compiler determines which method to call based on the inputs (parameters), not the outputs.

  • Example: If you call Calculate(5), and there are two versions—one returning an int and one returning a float—the compiler has no way to choose between them based on the input 5.

II. Performance Benefits

Because Method Overloading is Static, there is zero performance cost at runtime.

  • The CPU does not have to “search” for the right method.

  • The link is hard-coded into the binary during compilation.

  • This makes it superior for high-performance sections of a program (like mathematical calculations).

Ambiguity Trap

// Parent Class
class ClassA
{
    // Version 1: (Integer first, Decimal second)
    public void Add(int x, double y)
    {
        Console.WriteLine("Class A Result (int, double)");
    }
}

// Child Class
class ClassB : ClassA
{
    // Version 2: (Decimal first, Integer second)
    // Same name, but the types are swapped!
    public void Add(double x, int y)
    {
        Console.WriteLine("Class B Result (double, int)");
    }
}
ClassB obj = new ClassB();

// THE TRAP:
obj.Add(10, 10);

The solution To make the code work, you must teach the students to be explicit. They must tell the computer which number they want to be treated as a decimal.

  • To use Class A: obj.Add(10, 10.0); (The .0 makes it a double).

  • To use Class B: obj.Add(10.0, 10); (The .0 at the start forces Class B).

without Inheritance

class ClassA
{
    // Version 2: OVERLOADED method
    // Same name (Add), but takes THREE numbers instead of two
    public void Add(int x, int y, int z)
    {
        Console.WriteLine("Class B Result: " + (x + y + z));
    }
    
        // Version 1: Adds two whole numbers
    public void Add(int x, int y)
    {
        Console.WriteLine("Class A Result: " + (x + y));
    }
    
}