# Compile-Time Polymorphism: Overloading — Object-Oriented Programming (OOP)

Source: https://www.skillbyai.com/en/oop/p-static

> Use method and operator overloading and know how overloads are resolved.

## Same name, different parameters

**Polymorphism** means "many forms": one name or interface, several behaviours. **Compile-time** (static) polymorphism is resolved by the **compiler** from the declared types of the arguments. Its main form is **method overloading**: several methods with the same name but different **parameter lists** (number, types or order of parameters), such as `print(int)`, `print(String)` and `print(String, int)`. The return type alone cannot distinguish overloads. When choosing an overload, Java prefers exact matches, then widening primitive conversions, then boxing, then varargs, which occasionally produces surprises with `null` arguments or mixes of `int` and `long`. **Operator overloading** lets classes define operators: C++ (`operator+`), C# and Python (`__add__`, `__eq__`, `__lt__`) support it; Java does not, apart from built-in `+` for strings. Use overloading for genuinely equivalent operations on different inputs, not for unrelated behaviours that happen to share a name.

## Many forms of one name

Overloads share a name but differ in parameters; the compiler picks one from the argument types.

![One label at the top branching into three boxes of different shapes, each receiving a differently shaped input arrow.](assets/figures/oop/section-4-map.svg) — Figure 4.1 — Overload resolution by parameter types.

## Method overloading in Java and operator overloading in Python

The compiler chooses a Java overload from the argument types.

```java
public class Area {
    static double of(double radius)                { return Math.PI * radius * radius; }
    static double of(double width, double height) { return width * height; }
    static double of(double a, double b, double c) {        // triangle, Heron's formula
        double s = (a + b + c) / 2;
        return Math.sqrt(s * (s - a) * (s - b) * (s - c));
    }
}

double circle = Area.of(2.0);
double rect   = Area.of(3.0, 4.0);
double tri    = Area.of(3.0, 4.0, 5.0);

// Python: operator overloading with special methods
// class Vector:
//     def __init__(self, x, y): self.x, self.y = x, y
//     def __add__(self, other): return Vector(self.x + other.x, self.y + other.y)
//     def __eq__(self, other):  return (self.x, self.y) == (other.x, other.y)
// Vector(1, 2) + Vector(3, 4) == Vector(4, 6)   -> True
```

## Overloading is not overriding

Overloading: same name, different parameters, chosen at compile time, usually in one class. Overriding: same signature, in a subclass, chosen at run time. Mixing them up is the most common viva question slip.

**Quiz:** Which pair of Java methods is a valid overload?

- [ ] int total(int a) and double total(int a)
- [ ] void run() and private void run()
- [x] void log(String s) and void log(String s, int level)
- [ ] static void x() and void x()

*Answer:* void log(String s) and void log(String s, int level). Overloads must differ in their parameter lists; return type or modifiers alone are not enough.
