I have two abstract classes, lets call them Car
's and Wheel
's. I am handling different types of cars using some inheritance. So lets say there are two derivations MonsterTruckCar
and ToyCar
. Additionally there are different types of wheels that correspond to the Car
s, say TreadedWheel
's and PlasticWheel
's (the mapping does not necessarily need to be one-to-one from types of cars to types of wheels). Further Car
's are composed of Wheel
's.
The way I thought I would be able to do this in Java is by using an attribute of Car
's to be type ArrayList<Wheel>
. The issue I am having is that now when I want to use polymorphism on the Wheel
's I cannot because whenever I deal with a Wheel it is through an ArrayList
which is not a derived class of Wheel
's.
I thought I might be able to use bounded wildcards, or just a lot of switch statements to handle different combinations but I dont think either of those would be the greatest solutions. How can I handle such a structure?
Further, how do you add Wheel
's to the composition/collection in Car
's. That is, I need to be able to add a variable amount of concrete Wheel
's to a Car
, further this is going to be based off of some user input. so I would like to have a while loop in the default constructor that prompt the user if he/she wants to add another wheel and then if he/she does I add another Wheel
to whatever is aggregating/collecting them in Car
's.
Edit: Edited the names of the classes themselves from plural (Wheels
) to singular with a 's (Wheel
's) to clarify the relationship. Added the last paragraph which explains further the behavior I am looking for.
Add a generic parameter to your Car class that specified the wheel type. Here's a very basic implementation you can build on:
Includes updated requirements, which is tricky, but doable...
public interface Wheel {
void setSize(int diameter);
}
public static abstract class Car<T extends Wheel> {
private List<T> wheels = new ArrayList<T>();
protected Car(int numberOfWheels, Class<T> wheelClass) {
while (wheels.size() < numberOfWheels) {
T wheel;
try {
wheel = wheelClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(e); // simplified exception handling
}
wheel.setSize(5); // Ask user for wheel details etc
wheels.add(wheel);
}
}
public List<T> getWheels() {
return wheels;
}
}
public static class PlasticWheel implements Wheel { // or extends Wheel
@Override
public void setSize(int diameter) {
}
}
public static class ToyCar extends Car<PlasticWheel> {
public ToyCar() {
super(6, PlasticWheel.class); // or you could pass number of wheels in to this constructor
}
}
public static class TreadedWheel implements Wheel { // or extends Wheel
@Override
public void setSize(int diameter) {
}
}
public static class MonsterTruckCar extends Car<TreadedWheel> {
public MonsterTruckCar() {
super(4, TreadedWheel.class); // or you could pass number of wheels in to this constructor
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With