Sudarshan Sunder
Sudarshan Sunder

Reputation: 190

Inheritance in classes Java

class Foo {
    int number;
    public Foo(int x) {
        number = x;
        multiply();
    }
    public void multiply() {
        number = 2 * number;    
    }
    public int getNumber() {
        return number;
    }
}
class Bar extends Foo {
    int number;
    public Bar(int x,int y) {
        super(x);
        number = y;
        multiply();
    }
    public void multiply() {
        number = number * 3;
    } 
}
class Test {
    public static void main(String args[]) {
        Foo foo = new Foo(42);
        Foo bar = new Bar(42,24);
        System.out.println(foo.getNumber() + "\n" + bar.getNumber());
    }
}

The output of this code is 84 and 42 but no matter how I trace it, I end up with 84 and 72. Can anyone explain this in detail.

Upvotes: 2

Views: 111

Answers (2)

Akash Thakare
Akash Thakare

Reputation: 23012

In second case in Foo bar = new Bar(42,24); for super(x),

public Foo(int x) {
   number = x;//Now number in Foo is 42
   multiply();// of Bar will be called not of Foo
   //but currently number is 0 in Bar
}

Indirectly Foo#multiply(); has no effect in your second case for the number in Foo. So, multiply(); of Bar is called in constructor of Foo, your x which is now number in Foo remains unchanged which is 42. i.e. Bar(100,24) will give you number 100 in your case.

You have not override the getNumber in Bar you will have the number from the Foo which is 42.

Worth to note that number in Bar is now 72 because of number = y and multiply method of Bar, which you have not used.

Your constructor of Foo is similar to,

public Foo(int x) {
  number = x;
  this.multiply();// In second case 'this' refers to Bar and not Foo
  //So that control goes to multiply method of Bar and not Foo
}

Upvotes: 1

RealSkeptic
RealSkeptic

Reputation: 34648

Here is a trace:

Calling new Bar(42,4):

The 42 is passed to the super constructor. So it executes the body of:

public Foo(int x) {
    number = x;
    multiply();
}

The number it uses is its own number (the Foo.number which is hidden), but the multiply() it calls is the overridden one. Thus it calls:

public void multiply() {
    number = number * 3;
} 

But this refers to Bar.number, which at this stage is still 0 as it has not been initialized. So it remains 0. The number in Foo is not affected because that's not the number that appears in this version of multiply.

So at the moment we have Foo.number at 42, and Bar.number at 0.

We next continue to

    number = y;
    multiply();

Which puts the 24 in Bar.number, then multiplies it by 3.

But the getNumber() is not overridden. Which means that when you call bar.getNumber() you'll actually be getting the number from the Foo inside it. Which is 42.

Upvotes: 5

Related Questions