Understanding Method Overriding in Java
Method overriding in Java allows a subclass to provide a specific implementation of a method that is already defined in its superclass. However, the behavior differs between static and instance methods. Let's explore this with examples.
public class Main {
public static void main(String[] args) {
DerivedClass obj1 = new DerivedClass();
BaseClass obj2 = new DerivedClass();
// Static method behavior
obj1.display(); // Calls DerivedClass's static method
obj2.display(); // Calls BaseClass's static method
// Instance method behavior
obj1.execute(); // Calls DerivedClass's overridden method
obj2.execute(); // Calls DerivedClass's overridden method
// Field access based on reference type
System.out.println(obj1.name + "--" + obj2.name);
}
}
class DerivedClass extends BaseClass {
// Static method must match superclass's static method
public static void display() {
System.out.println("Overriding superclass static method");
}
@Override
public void execute() {
System.out.println("Overridden instance method in subclass");
}
}
class BaseClass {
String name = "BaseName";
public BaseClass() {
System.out.println("Base class constructor called");
}
public static void display() {
System.out.println("Superclass static method");
}
public void execute() {
System.out.println("Superclass instance method");
}
}
Key Observations:
- Static Methods: Invoked based on the reference type (compile-time binding). If the subclass does not override the static method, the superclass's version is called.
- Instance Methods: Invoked based on the object type (runtime polymorphism). Overridden methods always call the subclass's implementation.
Rules for Method Overriding
- Singature Match: The method name, parameters, and return type must exactly match the superclass method. Changing any of these means it's a new method, not an override.
- Access Moidfier: The subclass's overriding method must have an access level equal to or less restrictive than the superclass's method (e.g., protected can override a public method, but private cannot). This follows the Liskov Substitution Principle (LSP).
public class Computer {
// Default access (package-private)
int compute(int x) {
this.process();
System.out.println("Superclass method");
return x * 2;
}
}
public class Laptop extends Computer {
// Private access violates LSP (cannot override)
private int compute(int x) {
this.process();
System.out.println("Subclass method");
return x * 2;
}
}
In the above example, the subclass's private method does not override the superclass's default method, leading to a compile-time error. This design ensures that existing code using the superclass reference can still access the method after overriding.