1

I am taking a practice test for Java certification and got this question:

What will the following code print?

class Baap {

    public int h = 4;

    public int getH() {
        System.out.println("Baap    "+h);
        return h;
    }  
}  

class Beta extends Baap {

    public int h = 44;

    public int getH() {
        System.out.println("Beta    " + h);
        return h;
    } 

    public static void main(String[] args) {  
        Baap b = new Beta();  
        System.out.println(b.h + "    " + b.getH());  
        Beta bb = (Beta) b;  
        System.out.println(bb.h + "   " + bb.getH());  
    }  
}  

This is the answer:
Beta 44 4 44
Beta 44 44 44

My question: why is the 4 from the main class returned instead of the 44 from child class? Shouldn't it return 44?

I also don't see any variable that is shadowed by another variable with the same name that is closer in scope.

(Sorry for my english. I am French speaking.)

2
  • 5
    fields don't follow overriding. Commented Aug 2, 2014 at 8:45
  • a french speaking person writing Hindi classes :) Commented Aug 2, 2014 at 8:47

2 Answers 2

2

This is because Beta.h and Baap.h are different fields. In b.h, Baap.h is called (which is 4) and bb.h, Beta.h is called (which is 44). The difference is that b.getH() calls Beta.getH() (because b is new Beta()) but is reading Baap.h field, while bb.getH() calls Beta.getH().

Take a look at the main() method:

class Baap {  
    public int h = 4;  
    public int getH() { System.out.println("Baap    "+h); return h; }  
}  

class Beta extends Baap {
    public int h = 44;
    public int getH() { System.out.println("Beta    "+h); return h; }

    public static void main(String[] args) {
        Baap b = new Beta();
        System.out.println(b.h + "    " + b.getH());
        /* The string concatenation gets compiled to:
         * new StringBuffer().append(b.h).append("    ").append(b.getH()).toString();
         *                             \ This is Baap.h         \ This prints Beta 44 and returns 44 from Beta.h
         */
        // Printed "Beta 44" from b.getH().
        // Printed "4    44" from statements concatenation.
        Beta bb = (Beta) b;  
        System.out.println(bb.h + "   " + bb.getH());
        /* The string concatenation gets compiled to:
         * new StringBuffer().append(bb.h).append("    ").append(bb.getH()).toString();
         *                             \ This is Beta.h          \ This prints Beta 44 and returns 44 from Beta.h
         */
        // Printed "Beta 44" from b.getH().
        // Printed "44    44" from statements concatenation.
    }
}

From the Oracle JavaTM Tutorials - Inheritance, it was written that:

What You Can Do in a Subclass

  • The inherited fields can be used directly, just like any other fields.
  • You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).
  • You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
  • You can declare new fields in the subclass that are not in the superclass.

Read more:

Sign up to request clarification or add additional context in comments.

Comments

2

So your question is why b.h evaluates to 4 and not 44 in the following:

    Baap b = new Beta();  
    System.out.println(b.h + "    " + b.getH());  
                       ^^^ why is this 4?

The reason is that there is no data polymorphism in Java. Even though they share the same name, Baap.h and Beta.h are separate, unrelated fields.

When the compiler is resolving b.h it looks at the static (i.e. compile-time) type of b, not its dynamic (i.e. runtime) type.

The static type of b is Baap, so b.h resolves to Baap.h, which is 4.

3 Comments

So the return h; statement is the last to be processed in the sequence. I thought it was the second to be processed right after the b.getH(); method call. Super thank you
@Rahoul: Yes, the fact that getH() is both getting called in a println() and using println() confuses things.
In the System.out.println(b.h + " " + b.getH()) statement, I was expecting "b.h" to be printed first since it's the first member of the println statement, but it didn't. Could you tell me why's that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.