-2

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;
        }

    }    
}
Steve
  • 13
  • 3
  • the setGear method is not called at all. maybe you want to call it in your constructor? – Kent Jan 28 '12 at 00:51
  • my bad... It was supposed to be called in the constructor for the Bicycle class... assuming that setGear were used in the Bicycle class constructor to set the gear property - Fixed the example code... – Steve Jan 28 '12 at 01:06
  • 1
    @Steve It is very easy to write a simple test and see for yourself what Java does... – Andres F. Jan 28 '12 at 01:26
  • @AndresF. Yes you are correct but that would not help me to understand why I'm seeing the results that I'm seeing nor help me if I did something wrong in my code because I not sure how it should have worked to begin with. – Steve Jan 28 '12 at 01:43
  • Thanks for all the help but I found a better example with the answers I was looking for... http://stackoverflow.com/questions/4595512/java-calling-a-super-method-which-calls-an-overridden-method I guess I should have spent more time searching before asking... – Steve Jan 28 '12 at 01:51

6 Answers6

1

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

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
1

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

Michael Schmeißer
  • 3,407
  • 1
  • 19
  • 32
1

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.

user949300
  • 15,364
  • 7
  • 35
  • 66
0

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.

Unai Vivi
  • 3,073
  • 3
  • 30
  • 46
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.

Joni
  • 108,737
  • 14
  • 143
  • 193
-1

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
Mackintoast
  • 1,397
  • 5
  • 17
  • 25