He estado revisando las clases y métodos genéricos en Java y me encontré con esta pregunta en un artículo pasado
He intentado implementar la interfaz y las clases se propone en la cuestión, incluyendo el método de repostaje, y encontré ningún problema con que pasa el argumento de coches como un parámetro
interfaz motorizados
public interface Motorized {
public int getFuel();
}
clase de vehículos
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;
}
}
tipo de auto
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.");
}
}
método de prueba
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));
}
}
¿Puede alguien me explique cuál es el problema debe ser con esta pregunta y por qué mi aplicación de la misma no refleja este problema?
Las mentiras problema con el valor de retorno del método:
public static Motorized refuel(Motorized v)
Usted dijo que no tenía problemas para pasar de una Car
y que es una declaración completamente válida. Sin embargo, no se ha tratado de conseguir la espalda valor del refuel
método:
Car car = ...
Car refueled = refuel(car); // compiler error: Motorized is not assignable to Car!
El tipo de retorno es Motorized
aunque Car extends Motorized
, no se puede estar seguro de que el Motorized
ejemplo que se devuelve será siempre ser una Car
. Vea este ejemplo simplificado:
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();
}
Ahora se espera que un tal Car
, pero se obtiene una Motorbike
, por lo que incluso un reparto falla:
Car refueled = (Car) refuel(car); // ClassCastException, Motorbike is not a Car
Esto se puede hacer con los genéricos sin embargo:
public static <M extends Motorized> M refuel(M m) {
// refuel the motorized vehicle
return m;
}
Aunque si la estación de gas explota de nuevo, a continuación, el método tiene un problema. No sabe lo que M
realmente es. Por lo que este puede ser un salvavidas para los dolores de cabeza para usted.