Method Overloading and Method Overriding are two key concepts in object-oriented programming (OOP) that allow flexibility in how methods are used in Java. Though they sound similar, they serve different purposes.
1. Method Overloading:
- Definition: Method overloading is when multiple methods in the same class share the same name but have different parameters (i.e., the number or type of parameters). The methods are differentiated by their method signatures (parameter types, order, or number of parameters).
- Purpose: To allow different ways of calling the same method based on the arguments provided.
- Compile-time (Static) Polymorphism: Overloading is resolved at compile-time. The compiler determines which method to call based on the method signature.
Example of Method Overloading:
class Calculator { // Overloaded method with two parameters public int add(int a, int b) { return a + b; }
// Overloaded method with three parameters
public int add(int a, int b, int c) {
return a + b + c;
}
// Overloaded method with double parameters
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String args) {
Calculator calculator = new Calculator();
System.out.println(calculator.add(10, 20)); // Calls the first method
System.out.println(calculator.add(10, 20, 30)); // Calls the second method
System.out.println(calculator.add(10.5, 20.5)); // Calls the third method
}
}
- Key Points:
- The same method name (
add
) is used. - The method signature (number and types of parameters) is different.
- Method overloading occurs within the same class.
2. Method Overriding:
- Definition: Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. The method in the subclass must have the same name, return type, and parameters as the method in the superclass.
- Purpose: To allow a subclass to provide a custom implementation of a method that is inherited from a parent class.
- Runtime (Dynamic) Polymorphism: Overriding is resolved at runtime. The decision about which method to call is made dynamically, based on the object type.
- Annotations: The
@Override
annotation is used to ensure that the method is correctly overriding a method in the superclass.
Example of Method Overriding:
class Animal { // Method to be overridden public void sound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal {
// Overriding the sound method in Dog class
@Override
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String args) {
Animal myDog = new Dog();
myDog.sound(); // Calls the overridden method in Dog class
}
}
- Key Points:
- The method in the subclass (
Dog
) overrides the method in the superclass (Animal
). - Both methods have the same method signature (name, return type, and parameters).
- Method overriding occurs in an inheritance hierarchy (between superclass and subclass).
Key Differences Between Method Overloading and Method Overriding:
\| Aspect \| Method Overloading \| Method Overriding \|
\|-------------------------------\|----------------------------------------------------\|---------------------------------------------------\|
\| Definition \| Multiple methods with the same name but different parameters. \| Subclass redefines a method inherited from its superclass. \|
\| Where It Occurs \| In the same class. \| In different classes (superclass and subclass).\|
\| Method Signature \| Must be different (varying parameter types, order, or number). \| Must be exactly the same (same name, parameters, and return type). \|
\| Return Type \| Can have different return types. \| Must have the same return type. \|
\| Polymorphism \| Compile-time polymorphism (decided at compile-time). \| Runtime polymorphism (decided at runtime). \|
\| Purpose \| Provides multiple ways to call a method with different parameters. \| Provides a specific implementation of a method in a subclass. \|
\| Annotations \| No @Override
annotation used. \| @Override
annotation used to denote overriding. \|
\| Inheritance \| No inheritance is required. \| Requires inheritance (superclass and subclass). \|
\| Visibility \| Methods can have different visibility (public, private, etc.). \| The overriding method cannot reduce the visibility of the inherited method. \|
Example Summary:
- Overloading: Multiple methods in the same class with different parameters.
- Overriding: A subclass providing its own implementation of a method that is inherited from a superclass.
Conclusion:
- Method Overloading provides flexibility by allowing methods with the same name to accept different parameters, whereas Method Overriding allows a subclass to define its own behavior for an inherited method, providing runtime polymorphism and enabling dynamic behavior.