Question

Which method is called during Constructor chain execution with an overriding method? Given the following two classes I need to know which setGear method would be called when creating a MountainBike object. My real project has nothing to do with bicycles, I am trying to override a class to change the behavior of one method that is called in the constructor of the super class and I'm not sure how it should work...

public class Bicycle {
    public int cadence;
    public int gear;
    public int speed;

    public Bicycle(int startCadence,
                   int startSpeed,
                   int startGear) {
        setGear(startGear);
        setCadence(startCadence);
        setSpeed(startSpeed);
    }

    public void setCadence(int newValue) {
        cadence = newValue;
    }

    public void setGear(int newValue) {
        gear = newValue;
    }

    public void applyBrake(int decrement) {
        speed -= decrement;
    }

    public void speedUp(int increment) {
        speed += increment;
    }        
}

public class MountainBike extends Bicycle {
    public int seatHeight;

    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   

    public void setHeight(int newValue) {
        seatHeight = newValue;
    }

    public void setGear(int newValue) {
    if(newValue<4)
            gear = newValue;
        else{
            gear = 4;
        }

    }    
}
Was it helpful?

Solution

If you instantiate the overriding class, then its overriding methods will be the ones executed.

Bicycle bike;

bike = new Bicycle(1,2,3);
bike.setGear(8);//Bicycle's setGear is run

bike = new MountainBike(1,2,3,4);
bike.setGear(8);//MountainBike's setGear is run

-- Edit: to reflect OP edited question (setGear is now called from within Bicycle's constructor) --

Bicycle b=new MountainBike(1,2,3,4);

Given that you instantiate a MountainBike, MountainBike's setGear gets executed.

OTHER TIPS

If you call it, the subclass's method will execute. However, it's not currently being called.

There are some good answers here yet, but I would like to mention that you should consider to use composition instead. I have seen many projects where inheritance was used for features which could have done with composition in a much better way. In later project stages, this can lead to serious problems and code smells.

See "Favor composition over inheritance": Effective Java: Item 16

As other's have noted, it is the subclass' setGear that gets called.

However, I wanted to mention that calling overridden methods in a constructor is dangerous and frowned upon, especially if those methods rely upon fields of the subclass. For example, if MountainBike had a field, maxGear, and setGear referred to it (instead of a magic constant 4). The problem is that your MountainBike constructor looks something like:

public MountainBike(args...) {
  super(args);  // must come first!!!
  maxGear = 4;
}

When the Bicycle constructor calls setGear(), it will call MountainBike's setGear, but maxGear has not yet been set - it will be 0.

More generally, you should not let an object reference escape it's constructor, be it by passing "this" as a parameter to another class's method or by calling methods that can be overridden.

You should not call overridden methods from the superclass constructor even though you can. The reason is that the super class's constructor is run before the subclass's and the object state may be inconsistent. For example final fields in the subclass are not set yet.

Yes, overriding the base class method to create and accommodate new functionality in the derived class is what defines the subtype - polymorphic feature.

class A{methodA...}
class B extends A{methodA...}
A a=new B;
a.methodA(); <<<< this should call B's methodA
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top