I am trying to model the following situation in Java, but I suppose it might be a general OOP problem: I have 3 (or maybe more) different classes, which have some attributes and methods in common, and some attributes and methods which are specific to each of the classes.
So far, this is a classical inheritance situation.
The problem: The third class contains some attributes/methods identical to (only) the first class and some identical to (only) the second class. Polymorphism should also be used.
To be more specific: I want to model stations where people can borrow things: There are BikeStations
, CanoeStations
and BikeAndCanoeStations
, with one or more common behavior method(s) (for polymorphism).
As - at the first look - this seems to be a classical inheritance problem, one could model the classes as follows:
// Superclass (Station)
public abstract class Station {
// common attributes
// common methods
public abstract void doSomething();
}
// Subclass 1 (BikeStation)
public class BikeStation extends Station {
private int someBikeSpecificAttribute;
// more bike station specific attributes
public void doSomething() {
// bike station specific stuff
}
// more bike station specific methods
}
// Subclass 2 (CanoeStation)
public class CanoeStation extends Station {
private int someCanoeSpecificAttribute;
// more canoe station specific attributes
public void doSomething() {
// canoe station specific stuff
}
// more canoe station specific methods
}
// Subclass 3 (BikeAndCanoeStation)
public class BikeAndCanoeStation extends Station {
private int someBikeSpecificAttribute; // same as in BikeStation
private int someCanoeSpecificAttribute; // same as in CanoeStation
// more mixed station specific attributes
public void doSomething() {
// bike station specific stuff (same as in BikeStation)
// canoe station specific stuff (same as in CanoeStation)
}
// more mixed station specific methods
}
However, it doesn't feel right to just copy the attributes and methods/statements from the first two classes to the third. This just does not feel like good OOP. It produces redundant code and I cannot easily add other classes (stations) later.
So I thought about using Interfaces or even the Strategy Pattern, but this only solves the behavioral problem (i.e. the methods), if at all.
How would you model such a situation with good OOP (preferably in Java)?
(edited question to include/clarify the use of polymorphism.)
Looks like you are looking for composition. Difference between Inheritance and Composition is good read.
Basically BikeAndCanoeStation
will depend on BikeStation
and CanoeStation
and delegate the specific operation to them.
public class BikeAndCanoeStation extends Station {
private BikeStation bikeStation;
private CanoeStation canoeStation;
// more mixed station specific attributes
public void doSomethingBikeSpecific() {
this.bikeStation.doSomethingBikeSpecific();
}
public void doSomethingCanoeSpecific() {
this.canoeStation.doSomethingCanoeSpecific();
}
// more mixed station specific methods
}
I would still extract the methods in interfaces to be more clear what each implementor is supposed to do.