2012-09-27 55 views
6

Mi pregunta podría ser muy simple,Java: Para cada bucle, objetos extendidos iteración sobre

tengo una clase Result con algunos campos interiores, setters y getters.

Además, tengo la clase Special1Result que se extiende Result e incluye varios campos más y Special2Result con algunos datos más.

En diferentes clases Dispatcher, he escrito el siguiente método:

processResults(List<? extends Result> results), que sólo está familiarizado con Result (Necesito este método para consultar si hay campo específico en el objeto de resultado ampliados - Estoy utilizando anotaciones)

así que he decidido utilizar el extendido de cada bucle-: for (Result res : results) {}

Entonces, ¿cuál es la pregunta? Estoy tratando de encontrar en la web cómo escribir esto para el bucle para objetos extendidos, p. algo como esto for (? extends Results res: results){}

¿Es posible? ¿Cómo es la forma correcta de escribirlo?

Respuesta

2

Estoy tratando de encontrar en la web cómo escribir esto para el bucle para objetos extendidos, p. Ej. algo como esto

for (? extends Results res: results){} 

No, esto no es posible: no se puede escribir de forma estática de los componentes suministrados de forma dinámica en tiempo de ejecución.

¿Cuál es la forma correcta de escribirlo?

Ya lo están haciendo:

for (Results res: results) { 
} 

Si desea probar para Special2Result dentro de ese bucle, puede hacerlo, pero por lo general se dice que su diseño puede ser mejorado. Una mejor alternativa es utilizar un mecanismo de doble envío, como el Visitor Pattern, para ocultar los detalles del tratamiento especial para sus subclases.

+1

+1 Gracias, verificará cómo puedo usar el Patrón de visitante aquí. – Michael

+0

+1 para patrón de visitante. – EthanB

5

Todo lo que sabe acerca de un List<? extends Result> es que cada elemento será un Result - así que eso es todo lo que puede poner en la sintaxis del bucle mejorado.

Si necesita miembros que no se declaran en Result, tendrá que emitir dentro del bucle:

for (Result result : results) { 
    if (result instanceof CleverResult) { 
     CleverResult clever = (CleverResult) result; 
     // Use clever here 
    } 
} 

Piense en lo que iba a escribir si no fueras utilizando una mejorada para el bucle, todavía necesitarías escribir el elenco, ¿no?

Por supuesto, si usted sabe que la lista debe realmente solo contiene un tipo específico, siempre puede emitir incondicionalmente en el ciclo.

+0

+1, gracias, aunque no podía pedir lo que es el instanceof, ya que no sé los diferentes tipos de resultados especiales en el despachador clase – Michael

+0

@Michael: Entonces no podrías usar sensiblemente esa diferencia de todos modos, así que no importará, ¿verdad? ¿Por qué querrías * tener una variable de un tipo que no pudieras predecir? –

+0

se usa a menudo cuando programa con un equipo remoto, uno es responsable del marco y le permite ampliar sus objetos siempre que use un formato predefinido, por ejemplo, usando anotaciones. El producto en el que estoy trabajando implementa este diseño, y deseo ampliarlo un poco. Usando la anotación (@interface) puede indicar al usuario de la superclase qué campos son importantes, qué tipos deben inspeccionarse y más ... el diseñador de la infraestructura aún debe ser capaz de tratar con objetos extendidos por diferentes desarrolladores sin saber qué tienen implementado. – Michael

1

Java tiene borrado de tipo - los parámetros de tipo concreto de las colecciones no están presentes en el tiempo de ejecución.

Así que si tiene una Lista, el compilador de java se asegurará de que ningún código ponga nada en la lista que no sea una subclase de Resultado.

Por consiguiente, en el tiempo de ejecución, todo lo que puede saber es que los contenidos son todas subclases de Resultado, por lo que la única forma de recorrerlos es como un conjunto de referencias a Resultado, con cualquier comportamiento polimórfico presente como resultado de cualquier subclase que esté en la lista.

+0

+1, gracias, en el pasado pensé que si lanzas un objeto extendido más grande a un objeto superclase más pequeño, puedes perder algunas de las características en la clase – Michael

1

Dado que sus subclases de hormigón solo difieren por naturaleza de los campos, le sugiero que se beneficie de un polimorfismo simple.

Terminará con una clase de interfaz/resumen Result que define una clase de método execute() implementada por tantas clases o subclases como sea necesario que contengan acciones para hacer.

Por lo tanto, su código de cliente podría simplemente utilizar:

for (Result res : results){ //results being as a List<Result> type 
    res.execute(); 
} 
+0

+1, gracias, verificaré si ejecutar es una opción. – Michael

Cuestiones relacionadas