1

I am testing some polymorphism in java and my code looks like the following:

class Base {
        int value = 0;
        public Base(){
            System.out.println("Came Here And Value is: " + value);
            addValue();
        }
        String addValue(){
            System.out.println("Calling Bases' addValue and value is currently: " + value);
            value += 10;
            return "";
        }
        int getValue(){
            return value;
        }
}
class Derived extends Base{
        public Derived(){
            System.out.println("Calling Derived constructor and value currently is: " + value);
            addValue();
        }
        String addValue(){
            System.out.println("Came to Deriveds' addValue and value now is: " + value);
            value += 20;
            return "";
        }
        int getValue(){
            return value;
        }
}
public class MyClass {
    public static void main(String [] args){
       Base b = new Derived();
       System.out.println(b.getValue());

    }
}

So the thing here is, it prints 40 but I'm guessing that it should print 30. My thoughts are: new Derived first calls new Base, which calls addValue() and (as addValue() defined in Base adds up value by 10) value should be 10 at that time. then, Derived's addValue() is called which makes value 30 (because addValue() defined in Derived adds value up by 20). But instead, Base invokes it's child's addValue(). Can someone explain what's happening?

GeorgeTheGood
  • 65
  • 2
  • 13

4 Answers4

4

The misconception in your thought process is bolded:

new Derived first calls new Base, which calls addValue() and (as addValue() defined in Base adds up value by 10) value should be 10 at that time. then, Derived's addValue() is called which makes value 30 (because addValue() defined in Derived adds value up by 20).

Although addValue is placed inside the base class constructor, it is still calling addValue on this, like this:

this.addValue();

Well, what is this? It is a Derived class instance. What does the derived class's addValue do? It adds 20. That's why you got 40.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • And another question please. If i change the value variable as static and if i change both addValue() s as static it prints 30. so what's happening ? – GeorgeTheGood Jul 23 '17 at 12:08
  • @GeorgeTheGood This is because static methods are not affected by polymorphism. `addValue` placed in the base class constructor will call `Base.addValue`. – Sweeper Jul 23 '17 at 12:38
1

Yes, it is a pretty good example of how polymorphism works.

The parent addValue method is never called here, because of the overridden child method. It's called virtual method invocation. Consequently, if the child method is called twice, the result will be 40.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • And another question please. If i change the value variable as static and if i change both addValue() s as static it prints 30. so what's happening ? – GeorgeTheGood Jul 23 '17 at 12:10
  • @GeorgeTheGood, it is called [method hiding](https://stackoverflow.com/questions/16313649/what-is-method-hiding-in-java-even-the-javadoc-explanation-is-confusing). Here is no connection with an instance, so a class method gets called from the context where it was defined – Andrew Tobilko Jul 23 '17 at 12:14
1

It is because Derived does an implicit call to super, but it will call the overrided addvalue in Derived. This is why you should not call overridable methods in your constructor.

You can find this out by creating a break point on the first line in your main() and let a debugger show you the steps.

Mr. Wrong
  • 500
  • 7
  • 21
  • And another quick please. If i change the value variable as static and if i change both addValue() s as static it prints 30. so what's happening ? – GeorgeTheGood Jul 23 '17 at 12:11
1

Java behaves differently from C++ in this respect. In C++, the object is considered only partially constructed while the parent constructor executes, so it will execute the parent's method. In Java it will always execute the most-derived implementation of the method.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • And another quick please. If i change the value variable as static and if i change both addValue() s as static it prints 30. so what's happening ? – GeorgeTheGood Jul 23 '17 at 12:11
  • So it's calling `Base.addValue()` from `Base()`, and `Derived.addValue()` from `Derived()`, because static methods aren't overridden. – user207421 Jul 23 '17 at 12:30