2010-01-31 20 views
7

Bueno, escribí un código y todo lo que hacía era para bucles, pero cambiaba el método al que llamaba. Intenté usar un ciclo for para que fuera un poco más nítido (y por curiosidad para ver si se podía hacer), pero no se compila cuando lo hago de esta manera, porque no reconoce un elemento en una matriz como método, creo. Esto es lo que tengo:¿Puede Java almacenar métodos en matrices?

String[] moveArray = {moveRight,moveDown,moveLeft,moveUp}; 
for (i = 0; i < 4; i++) { 
    while (myWumpus.moveArray[i]) { 
     myWumpus.moveArray[i]; 
     generator.updateDisplay(); 
    } 
} 

Cuando intento compilar consigo

not a statement myWumpus.moveArray[i](); 
';' expected myWumpus.moveArray[i](); 

(Se refiere a la primera instrucción del bucle while)

Por lo tanto, creo que es tal vez porque ¿Lo estoy convirtiendo en una matriz de tipo String? ¿Hay algún tipo de Método? ¿Es esto posible? Cualquier solución bienvenida :). Además, puedo hacer que funcione usando 4 ciclos while, por lo que no es necesario que me muestres esa solución. ¡Gracias!

Respuesta

14

No puede almacenar métodos directamente en matrices. Sin embargo, puede almacenar objetos, que implementan el mismo método de manera diferente. Por ejemplo:

Mover[] moveArray = {new RightMover(), new DownMover() new LeftMover(), new UpMover() }; 
for (i = 0; i < 4; i++) { 
    while (myWumpus.moveArray[i]) { 
     moveArray[i].move(); 
     generator.updateDisplay(); 
    } 
} 
+0

Muy buena explicación. Me quedaré con los cuatro bucles por ahora, pero si es mucho más que eso, intentaré esto. – Paul

+0

Una variación es utiliza enums. Necesita pasar el objeto operado a través de un parámetro en la llamada al método, en lugar del constructor. –

5

No puede almacenar métodos en matrices en Java, porque los métodos no son objetos de primera clase en Java. Es una razón por la que algunas personas prefieren usar otros lenguajes como Python, Scheme, etc.

La solución alternativa es crear una interfaz que contenga un método, luego crear cuatro clases implementando esa interfaz: MoveRight, MoveLeft, etc. .. clases. Luego puede almacenar instancias de esas clases en su matriz y llamarlas de la misma manera.

+0

+1 Sí, las interfaces son mejores que usar el reflejo la mayoría del tiempo.:-) –

+0

java.lang.reflect.Method es un objeto de primera clase, pero estoy de acuerdo con la solución general que ha presentado –

+1

@Brian: Sí, pero es un objeto que representa el método, en realidad no es un método por -se. No puede "llamar" una instancia de Método (llama a un método en la instancia). – Draemon

3

Sí, puede almacenar métodos en matrices usando Reflection, sin embargo, es probable que lo que realmente quiere hacer en esta situación es usar polymorphism.

Como ejemplo de polimorfismo en relación a su problema - dicen que ha creado una interfaz de la siguiente manera:

public interface MoveCommand { 
    void move(); 
} 

A continuación, puede crear implementaciones de la siguiente manera:

public class MoveLeftCommand implements MoveCommand { 
    public void move() { 
     System.out.println("LEFT"); 
    } 
} 

etc. para el otro mover opciones A continuación, puede almacenar estos en un MoveCommand[] o la colección como un List<MoveCommand>, y luego iterar sobre la matriz/recogida llamando move() en cada elemento, por ejemplo:

public class Main { 

    public static void main(String[] args) { 
     List<MoveCommand> commands = new ArrayList<MoveCommand>(); 
     commands.add(new MoveLeftCommand()); 
     commands.add(new MoveRightCommand()); 
     commands.add(new MoveLeftCommand()); 

     for (MoveCommand command:commands) { 
      command.move(); 
     } 
    } 

} 

El polimorfismo es muy potente, y la anterior es una ejemplo muy simple de algo llamado Command Pattern. Disfruta el resto de tu implementación de Wumpus World :)

4

No puedes llamar a métodos como ese. Pero se puede utilizar la reflexión:

Sólo cambia la primera línea en el bucle while a:

Method m = myWumps.getClass().getMethod(moveArray[i]); // if the method is void 
m.invoke(myWumps); 

(que tendrá que declarar/coger unas pocas excepciones)

Pero es mejor evite la reflexión, y use el Command pattern en su lugar.

+0

¿Por qué es mejor evitar la reflexión? ¿El tiempo de reflexión es largo o la memoria abrumadora? Los códigos de arriba se ven muy bien. – byteBiter