Java Questions 31 - 40  «Prev  Next»

Casting and Interface Implementation in Java SE 25

Understand checked reference casts, pattern matching, inherited implementations, and interface contracts in Java SE 25.

  1. What is downcasting?

    Answer: Downcasting commonly means converting a reference to a more specific type, such as Animal to Dog. A cast changes the type of an expression used by the program; it does not transform the referenced object into a different class.

    For a checked cast, an incompatible non-null object causes ClassCastException. Casting null to a reference type produces null. A subsequent instance-method call through that null reference throws NullPointerException.

  2. What can the compiler verify about a reference cast?

    Answer: It checks whether the conversion is permitted between the compile-time types. This involves more than asking whether two classes appear in one inheritance chain: interfaces, arrays, final or sealed types, generic types, and disjointness rules can affect legality.

    A permitted checked cast can still fail at runtime. Some generic casts are unchecked because runtime type information cannot verify all type arguments. Prefer parameterized APIs and compiler-clean code rather than treating a warning as proof that a cast is safe.

  3. How does upcasting differ syntactically from downcasting?

    Answer: A widening reference conversion usually needs no explicit cast: Animal animal = new Dog();. A narrowing conversion normally needs cast syntax such as Dog dog = (Dog) animal;, or a pattern test that introduces a suitably typed variable.

    Neither operation copies the object. A safe widening conversion preserves the reference value. Before narrowing a reference whose runtime type is uncertain, use a suitable type test or work through the common supertype contract.

  4. Can an inherited method satisfy an interface implemented by a subclass?

    Answer: Yes. A compatible concrete method inherited from a superclass can satisfy an interface method even if the superclass did not declare that it implements the interface. The inherited method must meet the interface's access, return-type, signature, and checked-exception requirements.

    For example, an inherited public void run() can satisfy Runnable. An inherited protected run method is insufficient because Runnable's method is public. Merely finding a same-named method somewhere in the hierarchy is not enough.

  5. How can a cast-and-call sequence be simplified safely?

    Answer: When the type is known, ((Dog) animal).doDogStuff(); combines the cast and call. When the runtime type is uncertain, pattern matching combines the test with a local variable and avoids an unchecked assumption.

    public class PatternDog {
        static class Animal { }
        static class Dog extends Animal {
            void doDogStuff() { System.out.println("Fetch"); }
        }
        static void inspect(Animal animal) {
            if (animal instanceof Dog dog) {
                dog.doDogStuff();
            } else {
                System.out.println("Not a dog");
            }
        }
        public static void main(String[] args) {
            inspect(new Dog());
            inspect(new Animal());
            inspect(null);
        }
    }

    This prints Fetch, Not a dog, and Not a dog. The reference pattern does not match null, and dog is available only where the flow rules establish a match.

  6. What does the compiler check when a class implements an interface?

    Answer: It checks that the declaration and inherited members obey the interface rules. A concrete class must have valid implementations for its outstanding abstract-method obligations; inherited concrete methods and applicable defaults can supply them.

    The compiler also detects incompatible returns, insufficient access, conflicting defaults, and other declaration problems. It cannot prove that the implementation fulfills every documented behavioral promise, such as sorting correctly or preserving a business invariant; those require design and validation.



  7. Which exceptions may an interface implementation declare?

    Answer: Its checked exceptions must be compatible with the interface method's throws clause. It may narrow or omit checked exceptions. If the interface permits IOException, an implementation can declare FileNotFoundException, but cannot broaden the declaration to Exception.

    Unchecked exceptions are not restricted by this declaration rule. Saying an implementation “cannot throw any exception unless the interface declares it” is therefore wrong. When a method implements several declarations, it must satisfy all of their checked-exception constraints.

  8. Can an abstract class implement an interface?

    Answer: Yes. It can implement some or all of the required methods and leave unresolved abstract operations for concrete subclasses. Declaring the class abstract does not exempt its existing declarations from compatibility rules.

    This supports shared state and partial behavior behind a common interface. A concrete subclass must eventually satisfy the remaining obligations, either with its own methods or valid inherited implementations.


  9. Can a class implement more than one interface?

    Answer: Yes. A class can declare implements Runnable, AutoCloseable, for example. It still has at most one direct class superclass, while the interfaces describe multiple supported contracts.

    The combined requirements must be compatible. One implementation can satisfy several same-signature abstract methods when the return and exception rules allow it. Unrelated conflicting defaults may need an explicit override; incompatible return types can make the declaration impossible.

  10. Does an interface implement or extend another interface?

    Answer: It uses extends, as in interface Bounceable extends Moveable { }. An interface may extend multiple interfaces. A class uses implements to declare that it supports interface contracts.

    Modern interfaces can supply default method bodies, static utilities, and private helpers. That does not change the declaration syntax from extends to implements, and static or private interface methods are not inherited in the same way as public instance methods.

References: JLS: conversions, JLS: interfaces, and JLS: casts and instanceof.


SEMrush Software