views:

94

answers:

3

I have an abstract class Airplane, and two classes PassengerAirplane and CargoAirplane, which extend class Airplane. I also have an interface Measurable, and two classes that implement it - People and Containers.
So, Airplane can do many things on its own, and there is a method which allows measurable things to be added to the airplane (called addAMeasurableThing). The only difference between PassengerAirplane/CargoAirplane and just an Airplane is that addAMeasurableThing should only accept People / Containers, and not any kind Measurable things. How do I implement this?

I tried doing:
Airplane class:

public abstract Airplane addAMeasurableThing (Measurable m, int position);

PassengerAirplane class:

public Airplane addAMeasurableThing (Measurable m, int position) { if (m instanceof People)...

CargoAirplane class:

public Airplane addAMeasurableThing (Measurable m, int position) { if (m instanceof Containers)...

But when I was debugging it, I've noticed that addAMeasurableThing in the CargoAirplane class never gets called, because both methods have the same signature. So how can the appropriate PassengerAirplane/CargoAirplane's addAMeasurableThing be called, depending on the type of Measurable thing that is being passed on?

Thanks!

+5  A: 

Use generics:

abstract class Airplane<M extends Measurable>{
    public abstract Airplane addAMeasurableThing(M m, int position);
}

class PassengerAirplane extends Airplane<People>{
    @Override
    public Airplane addAMeasurableThing(People p, int position{ ... }
}
Matt McHenry
This worked as advertised! Thanks.
Milos
A: 

Try looking into making your Measurable class generic, and then use e.g. Measurable<People>, Measurable<? extends Foo>, etc.

JRL
I am new to Java, so the complete answer helped a bit more. Thanks.
Milos
A: 

It isn't the parameter type that determines which is called, it is the object type. So it depends if you created or passed in a PassangerPlane or a CargoPlane to the method that calls addAMeasurableThing. It is a larger design question of how you ensure that you only have the right type of Measurables to go into the plane. You might, for example, just throw an exception if the wrong measurable is added and then further up the call stack inform the user of the problem. It depends on what is determining the Measurable objects that need to be passed to the Airplane.

You also might want a static method on Airplane (or a new class AirplaneFactory) which gives you back the right subclass depending on a sample Mesurable that you pass it.

Yishai
This really helped. Thank you.
Milos