Implement subtypes for interface methods Java
I’ve been working on generic classes and methods in Java and ran into this issue in a past paper
I tried to implement the interface and class proposed in the problem, including the refuel method, and found no problem passing the Car parameter as a parameter
Motorized interface
public interface Motorized {
public int getFuel();
}
Vehicle class
public abstract class Vehicle{
private int fuel;
public Vehicle(int fuel) {
this.fuel = fuel;
}
public String toString(){
return("Fuel is: " + getFuel());
}
public int getFuel() {
return fuel;
}
}
Automotive category
public class Car extends Vehicle implements Motorized {
int seats;
public Car(int fuel, int seats) {
super(fuel);
this.seats = seats;
}
public int getSeats() {
return seats;
}
@Override
public String toString(){
return("Fuel is: " + getFuel() + "and the car has" + getSeats() + "seats.");
}
}
Test methodology
public class VehicleTest {
public static Motorized refuel(Motorized v) {
return v;
}
public static void main(String[] args) {
Car car = new Car(15, 5);
System.out.println(refuel(car));
}
}
Can someone explain to me what this problem should be and why my implementation doesn’t reflect out of it?
Solution
The problem is the return value of the method:
public static Motorized refuel(Motorized v)
You said that you had no problem passing the Car
, which is a completely valid statement. But you haven’t tried to get the value back from the refuel
method:
Car car = ...
Car refueled = refuel(car); compiler error: Motorized is not assignable to Car!
Although the Car extends
Motorized return type is Motorized, you cannot be sure that the returned Motorized
instance will always be a car
. See this simplified example:
public static Motorized refuel(Motorized v) {
try to refuel
uh oh... the gas station exploded
you have to change to a motorbike which just stands around
return new Motorbike();
}
Now you might expect a car
, but you get a motorcycle
, so even if the conversion fails:
Car refueled = (Car) refuel(car); ClassCastException, Motorbike is not a Car
You can do this using generics though:
public static <M extends Motorized> M refuel(M m) {
refuel the motorized vehicle
return m;
}
But if the gas station explodes again, then there is a problem with this method. It doesn’t know what M
actually is. So, this can be a lifesaver for your headache.