2
public class F { protected int a=0, b=0; public F() { a = 2; b = 2; } public void increase() { upA(); } public void upA() { a = a + 1; } public String toString() { return a+" "+b; } } 

 public class G extends F { public void increase() { super.increase(); upB(); } public void upA() { a = a + a; } public void upB() { b = b + 1; } } 

What is printed in the Output window by the following Java fragment?

 G g = new G(); g.increase(); System.out.println(g); 

Can someone explain to me why the answer is 4,3

(ie. the subclass method is called even though I have called super.increase() which calls the upA method in the superclass?)

2
  • 2
    Please format your code - it's horrible to read at the moment, and clarify your question - which subclass method is called unexpectedly? Commented Jun 17, 2014 at 11:35
  • I suggest you to Use Debugger for better understanding!! Commented Jun 17, 2014 at 11:41

4 Answers 4

6

All your methods are being called virtually, with overrides applying. So this code in F:

public void increase() { upA(); } 

... is invoking G.upA(), because the object it's calling upA() on is an instance of G.

So the execution flow for increase() is:

  • G.increase() calls super.increase()
    • F.increase() calls upA()
    • G.upA() executes (so a = 4)
  • G.increase() calls upB()
    • G.upB() executes (so b = 3)
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your comprehensive answer!
well explained @Jon Skeet. I was just wondering is it possible to strict any how so that the super.increase() will invoke the parent method F.upA() ?
@Saif: No, there's no way of calling it "non-virtually".
2

Think of increase() as being implemented like this

public void increase() { this.upA(); } 

and then ask yourself what object "this" is.

You are seeing "polymorphic" behaviour, and it's a really powerful feature of Object languages.

Note that you can write

 F gInDisguiseAsAnF = new G(); gInDisguiseAsAnF.increase(); 

and still get the same result. Which version of the upA() method is selected on the basis of the type that was newed.

Comments

1
 public void increase() { upA(); } 

is same as this.upA(), so the method in G was called, since this is instance of G.

calling super won't restrict your current instance only in super type.

1 Comment

Ahh I never thought of it like that, that makes a lot more sense now!
0

This is being called from increase() of F

public void upA() { a = a + a; // a=2+2 } 

Not,

 public void upA() { a = a + 1; //not a=2+1 } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.