0

I'm studying a chapter in java related to Inheritance, and i have a few questions.

I' have basic understanding how inheritance works ( overriding methods, information hiding, how to use private fields from superclass in a subclass etc ), but i have just one problem and i hope you might help me.

When superclass have non default constructor(s) - without parameters, that means that in a subclass i have to create new constructor (it can be default - without parameters ), but in a first statement must be superclass constructor call.

Ok, so far so good. I understand so far. In subclass you must call superclass constructor, matching any of constructors parameters.

But lets check following code: (Superclass)

public class Vehicle {

    private int numOfWheels;
    private double avgGallonsPerMile;   

    public Vehicle(int numOfWheels, double avgGallonsPerMile) {

        this.numOfWheels = numOfWheels;
        this.avgGallonsPerMile = avgGallonsPerMile;
    }
}

And another Subclass code:

public class Car extends Vehicle{

    public Car(double avgGallonsPerMile) {
        super(What should i write here?, avgGallonsPerMile);

        //force numOfWheels to 4;

    }   
}

Here is the exercise for subclass:

Each subclass contains a constructor that accepts the miles-per-gallon value as an argument and forces the number of wheels to the appropriate value—2 for a MotorCycle and 4 for a Car.

In subclass constructor i don't need numOfWheels field, because i will force it to 4 ( for car ) and 2(for motorbike) anyway.

But stil i need that data for superclass anyway. Where to get that data? What should as first parameter in call to superclass constructor.

But still this isn't the lonely case. I got lots of exercises that i don't need certain data in subclass constructor as parameters, BUT still i need them in superclass constructor call.

What should i do in such cases ?

I really hope you understood me, what i want to tell. It's kinda difficult.

maba
  • 47,113
  • 10
  • 108
  • 118
Firefoxx Pwnass
  • 135
  • 1
  • 9
  • "i don't need certain data in subclass" a) get over it or b) remove the field from the super class. – Peter Lawrey Sep 25 '12 at 14:16
  • Uhm... You say in the comment that you will force the number of wheels to 4. How will you do this? Hint: the numWheels field is private, so it can only be accessesed and modified/set within the Vehicle class. In other words, you need to send the appropriate value for numWheels to the superclass constructor from the Car constructor... – Alderath Sep 25 '12 at 14:21

3 Answers3

2

If its anyway the same 4 for cars and 2 for motorcycles than make if fix!

super(4, avgGallonsPerMile);

or the better way - declare a constant:

private static final int NUM_OF_WHEELS = 4;
..
super(Car.NUM_OF_WHEELS, avgGallonsPerMile);
schoeggii
  • 149
  • 3
  • 11
2

If you don't need a field in a super class then chances are it shouldn't be there. Instead you can do the following.

public abstract class Vehicle {
    private final double avgGallonsPerMile;

    public Vehicle(double avgGallonsPerMile) {
       this.avgGallonsPerMile = avgGallonsPerMile;
    }
    public double getAvgGallonsPerMile() { return avgGallonsPerMile; }
    public abstract int getNumOfWheels();
}

public class Car extends Vehicle{
    public Car(double avgGallonsPerMile) {
       super(avgGallonsPerMile);
    }
    public int getNumOfWheels() { return 4; }
}

public class Bicycle extends Vehicle{
    public Bicycle (double avgGallonsPerMile) {
       super(avgGallonsPerMile);
    }
    public int getNumOfWheels() { return 2; }
}

public class Tricycle extends Vehicle{
    public Tricycle (double avgGallonsPerMile) {
       super(avgGallonsPerMile);
    }
    public int getNumOfWheels() { return 3; }
}

BTW: Your car must be really inefficient if it uses gallons per mile of fuel.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • +1 for explaining that it shouldn't be in there if it isn't necessary in the superclass. – Jesper Sep 25 '12 at 14:24
  • avgGallonsPerMile may be fractional :) – Alexander Pogrebnyak Sep 25 '12 at 14:27
  • What's wrong with having the field as a part of the superclass and passing its value as an argument to the superclass constructor from the subclass constructor? (Like the person who created the homework question obviously intended) – Alderath Sep 25 '12 at 14:33
  • If you only expect it to be a class based constant and you feel it shouldn't be a field, then I wouldn't make it a field. If the superclass cannot be changed, you have no choice but to set it. – Peter Lawrey Sep 25 '12 at 14:36
  • 2
    If you need to _use_ the value of `getNumOfWheels` in the superclass constructor, then this is a really bad idea if `getNumOfWheels` is actually returning a member field in the subclass ([overridable method invocation in constructor](http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors)). If it's always returning a constant and/or the constructor doesn't use it, this is fine, ofc. – Brian Sep 25 '12 at 15:04
1

Very simple: if the number of wheels on a Car is always 4, them simply pass the value 4:

public Car(double avgGallonsPerMile) {
   super(4, avgGallonsPerMile);

    // ...
}
Jesper
  • 202,709
  • 46
  • 318
  • 350