What are the rules a method must follow to override a parent method in Java?
Four rules decide whether a method overrides or merely replaces a name. The name and the parameter types must match exactly. The return type must be the same or a subtype of the parent's. The visibility must be the same or wider, so a protected method cannot be replaced by a private one. And the throws clause may not add new checked exceptions, though it may declare fewer or none.
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
System.out.println(a.speak());
System.out.println(a.name());
}
}
class Animal {
String speak() { return "generic sound"; }
String name() { return "animal"; }
final String id() { return "fixed"; }
}
class Dog extends Animal {
String speak() { return "woof"; }
// String id() { return "dog"; } // will not compile: final method
// private String secret() { } // will not compile: visibility narrowed
}The example shows a normal override and two attempts that would not compile. The speak method in Dog matches the parent's name and parameters and returns a String, so it overrides. The commented attempts show the other rules: id is final in the parent, so it cannot be overridden at all, and a method cannot be made more restricted than the one it replaces, so private would be rejected.
Two related rules round out the picture. A method marked static hides rather than overrides, and a private method is not inherited at all, so declaring a private method with the same name in a subclass is a completely separate method. Neither is an override, and both are common sources of confusion.
The static method rule deserves emphasis because it is the subtle one. If the parent method is static, the child's same-signature method hides it, and the one that runs is chosen by the reference type rather than the runtime type. If the parent method is an instance method, the child's same-signature method overrides it and the runtime type decides. Mixing the two produces an error the compiler catches, which is why the compiler can be relied on here.