What is method overloading and overriding?
In Java, method overloading and overriding are two distinct concepts related to polymorphism, allowing methods to exhibit different behaviors in different contexts. Understanding these concepts is crucial for writing flexible and maintainable object-oriented code.
Method Overloading
Method overloading is a feature that allows a class to have multiple methods with the same name but different parameter lists. This is a form of compile-time (or static) polymorphism, as the compiler determines which method to call based on the arguments provided at compile time.
The key characteristic of overloading is that methods share the same name within the same class, but their signatures (the combination of method name and parameter types/order) must be unique. The return type alone is not sufficient to differentiate overloaded methods.
- Different number of parameters:
- Different types of parameters:
- Different order of parameters (if types are different):
class Calculator {
// Overload 1: Adds two integers
public int add(int a, int b) {
return a + b;
}
// Overload 2: Adds two doubles
public double add(double a, double b) {
return a + b;
}
// Overload 3: Adds three integers
public int add(int a, int b, int c) {
return a + b + c;
}
}
public class OverloadingDemo {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println("Sum of two integers: " + calc.add(10, 20));
System.out.println("Sum of two doubles: " + calc.add(10.5, 20.5));
System.out.println("Sum of three integers: " + calc.add(10, 20, 30));
}
}
Method Overriding
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. This is a form of runtime (or dynamic) polymorphism, as the JVM determines which method to execute based on the actual object type at runtime.
For a method to be overridden, the subclass method must have the exact same method signature (name, parameter list, and return type) as the superclass method. The @Override annotation is often used to ensure this and helps catch errors if the signature doesn't match.
- The method in the subclass must have the same name, same parameter list, and same return type as the method in the superclass.
- The access modifier of the overriding method cannot be more restrictive than the overridden method.
- The
finalandstaticmethods cannot be overridden. - Constructors cannot be overridden.
class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks: Woof Woof!");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat meows: Meow!");
}
}
public class OverridingDemo {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog(); // Runtime polymorphism
Animal myCat = new Cat(); // Runtime polymorphism
myAnimal.makeSound();
myDog.makeSound(); // Calls Dog's makeSound()
myCat.makeSound(); // Calls Cat's makeSound()
}
}
Key Differences: Overloading vs. Overriding
| Feature | Method Overloading | Method Overriding |
|---|---|---|
| Concept | Same method name, different parameters within the same class. | Same method signature (name, parameters, return type) in superclass and subclass. |
| Polymorphism | Compile-time (Static) Polymorphism. | Runtime (Dynamic) Polymorphism. |
| Happens In | Same class. | Two classes with an IS-A (inheritance) relationship. |
| Signature | Method signature must be different. | Method signature must be the same. |
| Return Type | Can be same or different (not a criterion for differentiation). | Must be same or covariant (subclass of the superclass's return type) since Java 5. |
| Access Modifier | Can be same or different. | Cannot be more restrictive than the overridden method. |
| Static/Final | Can overload static methods. | Cannot override static or final methods. |