Luca said:
Let's see another example about the same topic.
public abstract class AbstractVehicle {
public String GetType();
}
public abstract class ConcreteVehicle1 extends AbstractVehicle {
public String GetType() {
return "Vehicle1";
}
}
public abstract class ConcreteVehicle1 extends AbstractVehicle {
public String GetType() {
return "Vehicle2";
}
}
public class VehicleManager {
public void DoSomething(AbstractVehicle vehicle) {
if(vehicle.GetType.equals("Vehicle1"))
...
else if(vehicle.GetType.equals("Vehicle2"))
...
...
}
}
Which is the best way to plan this situation with polymorphism?
Thanks to what you taught me, I'd use an enum:
public enum VehicleType {
VEHICLE1,
VEHICLE2
}
And the rest of the code would be:
public abstract class AbstractVehicle {
public VehicleType GetType();
}
public abstract class ConcreteVehicle1 extends AbstractVehicle {
public VehicleType GetType() {
return VehicleType.VEHICLE1;
}
}
public abstract class ConcreteVehicle2 extends AbstractVehicle {
public VehicleType GetType() {
return VehicleType.VEHICLE2;
}
}
public class VehicleManager {
public DoSomething(AbstractVehicle vehicle) {
if(vehicle.GetType() == VehicleType.VEHICLE1)
...
else if(vehicle.GetType() == VehicleType.VEHICLE2)
...
...
}
}
The above is riddled with bugs.
Is it good to use an enumerator which contains the type/name of every
subclass?
1) Maybe you could use vehicle.getClass().getName() instead?
2) The need to do so suggests the design is poor. Whatever is happening
in the 'if' statements, should perhaps be replaced by an instance method
of AbstractVehicle that the subtypes implement (or override) differently.
Instead of
if(vehicle.GetType() == VehicleType.VEHICLE1)
...
else if(vehicle.GetType() == VehicleType.VEHICLE2)
...
...
Maybe you can do
vehicle.dotDotDot();
Here's a corrected SSCCE based on your buggy code above:
---------------------------------------8<---------------------------------
public class InheritTest1 {
public static void main(String[] args) {
InheritTest1 x = new InheritTest1();
x.new VehicleManager().doSomething(x.new ConcreteVehicle1());
}
public enum VehicleType {
VEHICLE1, VEHICLE2
}
public abstract class AbstractVehicle {
public abstract VehicleType getType();
}
public class ConcreteVehicle1 extends AbstractVehicle {
public VehicleType getType() {
return VehicleType.VEHICLE1;
}
}
public class ConcreteVehicle2 extends AbstractVehicle {
public VehicleType getType() {
return VehicleType.VEHICLE2;
}
}
public class VehicleManager {
public void doSomething(AbstractVehicle vehicle) {
if (vehicle.getType() == VehicleType.VEHICLE1)
System.out.println("Aha!");
else if (vehicle.getType() == VehicleType.VEHICLE2)
System.out.println("Oho!");
}
}
}
---------------------------------------8<---------------------------------
The main is a bit convoluted just so I can wrap everything into a single
class for ease of cut&paste&compile.
Here's another (better?) way to do achieve the same outcome:
---------------------------------------8<---------------------------------
public class InheritTest2 {
public static void main(String[] args) {
InheritTest2 x = new InheritTest2();
x.new VehicleManager().doSomething(x.new ConcreteVehicle1());
}
public abstract class AbstractVehicle {
public abstract void doSomething();
}
public class ConcreteVehicle1 extends AbstractVehicle {
public void doSomething() {
System.out.println("Aha!");
}
}
public class ConcreteVehicle2 extends AbstractVehicle {
public void doSomething() {
System.out.println("Oho!");
}
}
public class VehicleManager {
public void doSomething(AbstractVehicle vehicle) {
vehicle.doSomething();
}
}
}
---------------------------------------8<---------------------------------
Whether the above meets your needs is something I can't determine from
the example you posted. I think it illustrates a better way to think
about such problems but there will be some needs that can't be handled
this way.
Hoping this time the names for classes I used are better,
Much better
I'd have used Car and Truck instead of ConcreteVehicle1 and
ConcreteVehicle2 but maybe I have too much difficulty with abstract
expressions of concepts.