Java - parent class is calling a method from a child class?

Viewed 4438

Sorry, I am still new to coding and may not have all the terminologies down. Hopefully, you will still understand my question. The output that I want to get is:

"Cost for Parent is: 77.77"
"Cost for Child is: 33.33"

However, I am getting this:

"Cost for Parent is: 33.33"
"Cost for Child is: 33.33"

Can anyone understand why? I have a simplified version of my code below but kept the logic behind it the same...

public class Parent{
    public double calculateCost(){
        return 77.77;
    }

    @Override
    public String toString(){
        return "Cost for Parent is: " + calculateCost();
    }
}

public class Child extends Parent{
    @Override
    public double calculateCost(){
        return 33.33;
    }

    @Override
    public String toString(){
        return super.toString() + "\nCost for Child is: " + calculateCost();
    }

    public static void main(String[] args){
        Child child1 = new Child();
        System.out.println(child1.toString());
    }
}

In my mind, the toString() in the Child class should be calling the toString() from the Parent class (thus, the calculateCost() from Parent class) then adding to it with a calculateCost() from Child. I'm guessing the super in super.toString() does not apply to calculateCost() that it contains.

Also, I know I can get around it by writing the toString() in the Child class like this:

    @Override
    public String toString(){
        return "Cost for Parent is: " + super.calculateCost() + "\nCost for Child is: " + calculateCost();
    }

but the point is that I don't want to repeat code and that I'd rather add to the previous toString() method that I am overriding. Please help or direct me (not sure what I should be googling for...) Thanks!

8 Answers

I decided to put a private function prefixed with an underscore in my parent class in those cases to be able to target that specific function and still have the general public overridable function in my parent implementation.

public class Parent{
    public double calculateCost(){
        return _calculateCost();
    }

    // Add this parent specific implementation
    private double _calculateCost(){
        return 77.77;
    }

    @Override
    public String toString(){
        return "Cost for Parent is: " + _calculateCost();
    }
}

public class Child extends Parent{
    @Override
    public double calculateCost(){
        return 33.33;
    }

    @Override
    public String toString(){
        return super.toString() + "\nCost for Child is: " + calculateCost();
    }

    public static void main(String[] args){
        Child child1 = new Child();
        System.out.println(child1.toString());
    }
}

I think the reason for this is the behaviour of JVM because in Java whenever we call a method on an object, which belongs to a class that inherits from some other class, the JVM checks whether that method is being overrided or not by the subclass so despite of overriding toString() method from subclass the call to calculate cost() resolves to subclass' version.

Related