OCP Stage 2 Problem 1.18 – Explanation

Given the classes:

class Runner {
    public void run() { System.out.println("Running..."); }
}
class Code extends Runner {
    public void run() { System.out.println("It's alive!"); }
}
class Pantyhose extends Runner {
    public void run() { System.out.println("Not again!"); }
}
class Snippet extends Code {
    public void test() { System.out.println("Testing...");
    }
}

Which code fragment will throw a runtime exception?

A. Runner r = new Code();
r.run();
B. Code c = new Pantyhose();
c.run();
C. Code c = new Snippet();
c.test();
D. Runner r = new Code();
((Snippet) r).test();

E. Runner r = new Snippet();
((Snippet) r).test();

 

The correct answer is D.

 

Just like we did on the OCA exam, in questions with explicit casts it is better to draw simple diagrams that show inheritance relationship between classes (ref.to Nailing 1Z0-808, page 315), or at least write down those relations in shorthand, like in:

Runner <- - - - Code <- - - - Snippet
   \- - - - - - Pantyhose

By looking at this inheritance graph, we can easily conclude that:

  • option A is syntactically valid and the run() method is indeed available to the r object; what’s more, since no casts are involved here, the code won’t throw an exception;
  • option B is invalid because Code and Pantyhose are not related in terms of inheritance;
  • the first LOC in option C is valid as Snippet is narrower than Code but the c object has no access to the test() method because Code didn’t define such a method;
  • option D is valid although casting r of the wider Runner type to narrower Snippet will throw an RTE, namely ClassCastException; and lastly
  • option E compiles and runs readily outputting “Testing‚Ķ”.

 

Takeaway:
Explicit casts are prone to throwing a CCE. To compile, implicit casts must have wider type on the left-hand side.

 

Objective:
Java Class Design

Sub-Objective:
Implement polymorphism

 

Leave Comment

Your email address will not be published.