OCP Stage 2 Problem 1.22 – Explanation


class Father {
    public String who;
    Father getRelation() {
        who = "Father";
        return this;

class Son extends Father {
    protected Son getRelation() {            // n1
        who = "Son";
        return this;

class Grandson extends Son {
    public Grandson getRelation() {          // n2
        who = "Grandson";
        return this;
    public static void main(String[] args) {
        System.out.print(new Grandson().getRelation().who);

What is the result?

A. Father
B. Son
C. Grandson
D. Compilation fails due to an error on line n1.
E. Compilation fails due to an error on line n2.


The correct answer is C.


This is an illustration of polymorphism in action: since the getRelation() method is overridden, the actype (that is, the object type at runtime) determines which version of the getRelation() method is invoked. Polymorphism in Java occurs when a method in a subclass has the same name as a method in the superclass, but it performs different implementation.

If the actype were Son, then the output would be “Son”. Likewise, if the actype were Father, then the output would be “Father”.

As for compilation failures, rules of method overriding dictate that overriding methods can specify access modifiers that are less restrictive than the original method’s, and public is more open than protective, which is more open than the default-level access. What’s more, Java allows an overriding method to return a subtype of the return type of the original method; this is known as covariant return types. All of this makes options D and E invalid.



Non-static and non-final methods are potentially polymorphic. If such a method has been overridden, its overriding version will run. Fields are not polymorphic so their value is determined by the object’s reftype rather than actype.


Java Class Design

Implement polymorphism

Leave Comment

Your email address will not be published.