Review method access, dynamic dispatch, overload resolution, and checked-exception contracts in Java SE 25.
Answer: No. An override must preserve or widen the access permitted by the overridden declaration. A public method must remain public; a protected method can remain protected or become public. An inherited package-access method can be overridden with package, protected, or public access where the inheritance rules allow it.
For example, changing a parent's public void work() into a child's protected void work() is a compile-time error. Private methods are not inherited or overridden, and a package-access method is not simply available to every subclass in another package. Use @Override to catch declarations that do not actually override the intended method.
Answer: An override cannot introduce checked exceptions that the overridden declaration does not permit. Each checked exception declared by the override must be compatible with the parent's throws clause. The override may declare fewer checked exceptions, narrower subtypes, or none.
RuntimeException and Error subclasses are unchecked and are not restricted by this throws-clause rule. When one implementation overrides declarations from multiple interfaces, it must satisfy all their checked-exception constraints. These compile-time permissions do not remove the need to respect the API's documented behavior.
Answer: After compile-time method selection, an ordinary virtual instance call dispatches to the applicable overriding implementation for the actual receiver object. A variable's superclass or interface type does not change the object's runtime class.

The diagram illustrates one implementation model, not a requirement that every JVM perform a particular virtual-table lookup on every call. A JVM can interpret code or use compiled and inlined code while preserving Java's behavior. Interface calls also have their own invocation rules; describing every call as a single invokevirtual instruction is inaccurate.
Answer: A reference to a subclass object can be widened to a compatible superclass type, such as Animal animal = new Dog();. This creates another way to refer to the same object, not a new Animal object.
The reverse assignment is not automatically valid. An Animal variable might refer to a different subclass, so obtaining a Dog reference requires an appropriate narrowing conversion or pattern test. Generic type arguments also matter: List<Dog> is not a subtype of List<Animal>.
Answer: Overriding supplies an implementation for an eligible inherited instance method, subject to signature, return-type, access, and exception rules. Overloading provides same-named methods with distinct parameter signatures. Overloads may be declared together or arise through inheritance; they are not confined to a single class's source file.
public class OverrideSelection {
static class Parent {
String message() { return "Parent"; }
}
static class Child extends Parent {
@Override String message() { return "Child"; }
}
static String describe(Parent value) { return "Parent overload"; }
static String describe(Child value) { return "Child overload"; }
public static void main(String[] args) {
Parent value = new Child();
System.out.println(describe(value));
System.out.println(value.message());
}
}
This prints Parent overload and Child. Overload selection uses compile-time information; virtual dispatch uses the actual receiver. Changing only a return type does not create an overload. Static methods are hidden rather than overridden.
Answer: It generally declares an overload rather than an override when the signatures are distinct and otherwise legal. For example, work(String) does not override work(Object). The inherited Object-parameter method can still be selected for a call.
Changing parameter names alone does not change a signature. Generic erasure can also make apparently different declarations clash rather than form valid overloads. Keeping @Override on an intended override helps catch accidental parameter changes.
Answer: No. The parent can declare FileNotFoundException or a compatible superclass such as IOException. FileNotFoundException is a checked subtype of IOException, so narrowing the throws clause this way is allowed.
If the parent declares no checked exceptions, the override cannot add FileNotFoundException to its throws clause. It can handle that exception internally. Unchecked exceptions follow different rules and need not appear in the parent's declaration.
Answer: Callers checked against the parent method are required to handle only that method's declared checked exceptions. Allowing a broader checked exception in an override would invalidate that compile-time contract.
For example, a parent declaring IOException cannot be overridden by a method declaring the broader Exception. A caller prepared for IOException is not necessarily prepared for every checked Exception. The compiler rejects the declaration even if a particular implementation happens not to throw the broader exception today.
Answer: It may declare checked exceptions permitted by every overridden contract, including narrower subtypes, and may omit checked exceptions entirely. It may also declare unchecked exceptions, although such declarations do not create a catch-or-declare obligation.
A throws clause describes possible propagation, not a requirement to throw an exception on every call. Catching an exception inside the method and completing normally is different from allowing it to escape to the caller.
Answer: No. It can omit permitted checked exceptions. A parent method might declare IOException while a child's implementation completes without any checked exception and declares none.
Call-site checking still uses the selected compile-time declaration. Calling through a parent-typed expression may require handling IOException even when the current object is the child. Calling the child's narrower declaration directly can avoid that obligation, provided no other part of the expression introduces it.
References: JLS: overriding and overloading, JLS: exceptions, and JLS: method invocation.