What conditions must a subclass method satisfy to override a method inherited from its superclass?
answer
- Same name + same params = signature
- Return type: same or covariant (subtype)
- Access widens, exceptions narrow
- static/final/private can't be overridden
- @Override = compiler-checked
basics
~20 sThe subclass method must have the same name and same parameter list as the superclass method, and the same (or a compatible) return type. If the name or parameters differ, it is not an override - it becomes a separate or overloaded method.
solid answer
~40 sTo override, the subclass method must share the superclass method's name and exact parameter list (the 'signature'). The return type must be identical or a subtype (covariant return). The method being overridden cannot be static, final, or private, and instance-overriding only applies to non-static methods. Access may stay the same or widen, never narrow. Declared checked exceptions may only be the same, narrower, or fewer - you cannot add new broader checked exceptions. Add the @Override annotation so the compiler verifies you actually matched a superclass method; a typo in the name or a changed parameter would otherwise silently create a new method instead of overriding. Overriding is the basis of runtime polymorphism: the JVM picks the implementation based on the object's actual type, not the reference type.
code
java · 15 linesclass Animal {
protected Animal reproduce() throws Exception {
return new Animal();
}
}
class Cat extends Animal {
@Override // compiler verifies this really overrides
public Cat reproduce() { // public widens protected; Cat is covariant; no checked exception
return new Cat();
}
}
Animal a = new Cat();
// Dynamic dispatch: Cat.reproduce() runs even through an Animal referencego deeper
Can state that an override needs the same method name and same parameters, and knows @Override should be added.
Articulates the full rule set - signature match, covariant returns, access-widening, checked-exception narrowing - and explains why @Override prevents accidental overloads.
Connects each rule back to Liskov substitutability (why callers through the supertype must not be surprised) and distinguishes overriding from hiding/overloading crisply.
Frames the rules as the compiler enforcing behavioral subtyping, discusses API-evolution implications (covariant returns and exception narrowing as safe contract refinements), and the cost of over-broad throws clauses on subclass flexibility.
## What overriding is **Inheritance** lets a class (the *subclass* or *child*) reuse and extend another class (the *superclass* or *parent*) via `extends`. The subclass receives the parent's non-private methods. **Overriding** means the subclass provides its *own* implementation of a method it inherited, replacing the parent's version *for instances of the subclass*. This is the engine of **polymorphism**: when you call the method through a parent-typed reference that actually points to a child object, the child's version runs. That decision is made at runtime (**dynamic dispatch** / **late binding**), not at compile time. ## The rules, term by term A **method signature** is the method's *name plus its ordered parameter types* (return type is NOT part of the signature in Java). To override, the subclass method must: 1. **Same name + same parameter list (same signature).** If parameters differ, you are *overloading* (a different, unrelated method), not overriding. `eat()` and `eat(String food)` are two distinct methods. 2. **Same or covariant return type.** *Covariant* means the override may return a *subtype* of the parent's return type. If `Animal reproduce()` is the parent, `Cat reproduce()` is a legal override because `Cat` is an `Animal`. A wider or unrelated return type is a compile error. 3. **Access may only widen, never narrow.** If the parent method is `protected`, the override can be `protected` or `public`, but not `private` or package-private. Narrowing would let a subtype refuse access the supertype promised - breaking substitutability. 4. **Checked exceptions may only narrow.** A *checked exception* is one the compiler forces you to declare with `throws` or handle. The override may throw the same checked exceptions, *subtypes* of them, *fewer* of them, or none - but it may NOT add a *new or broader* checked exception. (Unchecked exceptions - `RuntimeException` and its subtypes - are unrestricted.) Reason: code calling through the parent reference only prepared for the parent's declared exceptions. 5. **The method must be overridable.** `static`, `final`, and `private` methods cannot be overridden. A `static` method with the same signature is *hidden*, not overridden (resolved by reference type, not runtime type). A `private` method is invisible to the subclass, so a same-named subclass method is brand new. `final` explicitly forbids overriding. ## @Override `@Override` is an annotation you place on the subclass method. It does not change behavior; it asks the **compiler to verify** that this method really overrides (or implements) a supertype method. If you misspell the name or get a parameter type wrong, the compiler emits an error instead of silently creating a useless new method. It is a cheap, strongly-recommended safety net. ## Worked picture ```java class Animal { protected Animal reproduce() throws Exception { return new Animal(); } } class Cat extends Animal { @Override public Cat reproduce() { return new Cat(); } // widened access, covariant return, fewer exceptions } ``` All three relaxations above are legal: `public` widens `protected`; `Cat` is a covariant `Animal`; throwing nothing narrows the `throws Exception`. With `Animal a = new Cat(); a.reproduce();` the **Cat** version runs - that is dynamic dispatch driven by a valid override.
- If I change only the return type of an override to an unrelated type while keeping name and parameters identical, what happens?Compile error. Java does not allow two methods with the same signature but incompatible return types. The override must return the same type or a covariant subtype; an unrelated return type is rejected.
- Does @Override do anything at runtime?No. It is a compile-time-only safety check (source/class-retained, not used by the JVM for dispatch). It causes a compile error if the annotated method does not actually override a supertype method, but it has zero runtime effect.
Overriding is like a regional branch of a company replacing the head-office procedure with its own version of the same procedure - same name on the door, same inputs expected, but it can offer a more specific result and may NOT impose stricter access rules or surprise customers with new failure modes the head office never warned about.
saying these in an interview costs you the question
- Thinking changing the parameter list still overrides - that is overloading, a different method.
- Believing the override may throw any exception it likes - new/broader CHECKED exceptions are forbidden (unchecked are fine).
- Saying access can be narrowed in an override - it can only stay the same or widen.
- Claiming @Override is required for overriding to work - it is optional but strongly recommended.