5

The following code prints output as 40 instead of 30. I'm not able to figure out the solution. Please help with the code.

class Base {

  int value = 0;

    Base() {
      addValue();
    }

    void addValue() {
      value += 10;
    }

    int getValue() {
      return value;
    }
}

class Derived extends Base {

  Derived() {
    addValue();
  }

  void addValue() {
    value +=  20;
  }
}

public class Test{

  public static void main(String[] args) {
    Base b = new Derived();
    System.out.println(b.getValue());
  }
}

  The implicit super reference in Derived constructor calls Base constructor which in turn calls method addValue() in the class Base results in value variable as 10 and then addValue() in the Derived class should add 20 to value 10. So the final output is 30.

But the code prints 40.

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
Rakesh
  • 53
  • 4

6 Answers6

8

The addValue method is overridden in the Derived class. When a method is overridden, calling a method on an instance of this class always calls the overridden version, even when the call happens in the base class.

yole
  • 92,896
  • 20
  • 260
  • 197
  • yes, but method call is done in the constructor which starts executing at the object creation new Derived() and calls Derived class constructor which again calls Base class constructor because of implicit super() reference and thus Base class addValue() executes first followed by addValue() in Derived class. – Rakesh Oct 12 '18 at 14:01
  • No, this is not how it works. A Derived object is a Derived object from the very beginning, and all method calls will call the implementations in the Derived class, even if the call happens before the Derived constructor has executed. – yole Oct 12 '18 at 14:05
4

In class Derived, the method void addValue() points to the method defined in Derived, not in Base

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
2

Most probably when you extend the Base class

class Derived extends Base {

  Derived() {

    addValue();

  }

  void addValue() { //here

    value +=  20;

  }

}

you put the method name same in the Base Class and this overrides the default one which is:

   void addValue() {
      value += 10;
    }

So, the output is 40 -> 20 + 20

Rarblack
  • 4,559
  • 4
  • 22
  • 33
1

As others have got there before me: addValue is overridden in Derived, as it is an accessible method with the same name and same parameter types. Typically you would add the @Override annotation to the override method. The method in the derived class even though the base class is still under construction.

Not all languages do the same thing. C++, for example, will not run overridden methods from derived class whilst the base constructor is still running. The equivalent program in C++ does show 30.

#include <iostream>

class Base {
public:
    int value;

    Base() : value(0) {
      addValue();
    }

    virtual void addValue() {
      value += 10;
    }

    int getValue() {
      return value;
    }
};

class Derived : public Base {
public:
  Derived() {
    addValue();
  }

  virtual void addValue() {
    value +=  20;
  }
};

int main() {
    Base *b = new Derived();
    std::cout << b->getValue() << std::endl;
}
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
0

addValue() is override in Derived class and you created a Derived class object. So whenever the addValue() called by this instance. Always methos is called of Derived class. So thats why addValue() of Derived class called twice. Once in the Base class constructor and second in Derived class constructor.

Khalid Shah
  • 3,132
  • 3
  • 20
  • 39
  • But Derived class constructor will implicitly point to parent class constructor using super() reference and Base class constructor starts executing which should call addValue() in the Base class – Rakesh Oct 12 '18 at 13:57
  • Yes. When in the base class addValue() called it executes the derived class function because it has the reference of derived class. If function is not overidden in the Derived class then the base class function is called. – Khalid Shah Oct 12 '18 at 14:07
  • If you put the add value code in both constructors like in base constructor write code value+=10 and in derived constructor write value+=20. Then your final value will be 30. – Khalid Shah Oct 12 '18 at 14:12
0

As others discussed earlier Method Overriding property applies to method call in the base class well.

By this java applies Run Time Polymorphism i.e., Based on the object that is invoked at run time, the method which is to be executed is decided. For e.g.,

  • If super class object is used to invoke the method, then super class method will be executed.
  • If sub class object is used to invoke the method, then sub class method will be executed.

If we don't want to override, we can make the parent method as private instead of default private package. Now we will be getting 30 as output. As the method which cannot be inherited then it cannot be overridden

class Base {

    int value = 0;

    Base() {
        addValue();
    }

    private void addValue() {
        value += 10;
    }

    int getValue() {
        return value;
    }
}

class Derived extends Base {

    Derived() {
        addValue();
    }

    void addValue() {
        value +=  20;
    }
}

public class Test{

    public static void main(String[] args) {
        Base b = new Derived();
        System.out.println(b.getValue());
    }
}

Now, the output is 30.

Navarasu
  • 8,209
  • 2
  • 21
  • 32