digamos que tenemos un programa que contiene dichas clases:Java problema colecciones covarianza
public interface AbstractItem {
}
public SharpItem implements AbstractItem {
}
public BluntItem implements AbstractItem {
}
public interface AbstractToolbox {
//well the problem starts here...
public List<AbstractItem> getItems();
}
public ExpensiveToolbox implements AbstractToolbox {
private List<SharpItem> items = new ArrayList()<SharpItems>;
public List<SharpItem> getItems() { return this.items; }
}
public CheapTooblox implements AbstractToolbox {
private List<BluntItem> items = new ArrayList()<BluntItem>;
public List<BluntItem> getItems() { return this.items; }
}
fácil, ¿verdad? Bueno digamos que ahora queremos hacer un método como este (de alguna clase al azar):
public void doImportantStuff(AbstractToolbox toolbox) {
//important stuff!
//this obviously won't work
List<AbstractToolbox> items = toolbox.getItems();
//do some stuffwith all items
}
Ahora el problema es que en Java colecciones con los genéricos no son covariantes (la esperanza de que es el término que estoy buscando) y no puedo asignar un ArrayList<ExpensiveToolbox>
a un List<AbstractToolbox>
. La única solución que puedo ver aquí es duplicar el código y hacer una versión para cada tipo, pero eso obviamente apestaría (¿y si tuviéramos más clases implementando AbstractToolbox con diferentes listas?). Oh, obviamente, la segunda solución sería soltar los genéricos y hacer una lista normal, pero ¿es una buena práctica?
¿Existen patrones/prácticas de diseño para abordar estos problemas?
@Edit: ok, entonces podría no ser lo suficientemente preciso. Quiero que todas las clases que extienden AbstractToolbox tengan una Lista de ciertas clases que extiendan AbstractItem y luego quiero un método que tome un AbstractToolbox como parámetro y haga algo en los elementos de su lista (usando las clases que se definirían en AbstractItem para que todos los elementos de todas las listas posibles realmente los tengan).
Para aclarar, no le gustaría que su doImportantStuff que tiene: List <> AbstractItem artículos = toolbox.getIems(); – MikeTheReader
¿Qué quieres decir con "Fácil, ¿verdad?" ¡Tu primera sección no se compila y no debería! –
Bueno, pensé que sería fácil para SO. Quiero decir, obviamente, * I * estoy teniendo problemas con eso;) –