2010-01-31 4 views
7

Nun, ich schrieb etwas Code und alles, was ich tat, war für Schleifen, aber ändern, welche Methode ich angerufen habe. Ich habe versucht, eine for-Schleife zu verwenden, so dass es ein bisschen sauberer wäre (und aus Neugierde, um zu sehen, ob es gemacht werden könnte), aber es kompiliert nicht, wenn ich es so mache, weil es ein Element nicht erkennt ein Array als Methode, denke ich. Das ist, was ich habe:Kann Java Methoden in Arrays speichern?

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

Wenn ich kompilieren versuche ich

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

(es auf die erste Anweisung in der while-Schleife bezeichnet)

Also, ich denke, es ist vielleicht, weil ich mache ich ein Array vom Typ String? Gibt es eine Art Methode? Ist das überhaupt möglich? Irgendwelche Lösungen willkommen :). Außerdem kann ich es mit 4 While-Loops zum Laufen bringen, so dass Sie mir diese Lösung nicht zeigen müssen. Vielen Dank!

Antwort

14

Sie können Methoden nicht direkt in Arrays speichern. Sie können jedoch Objekte speichern, die die gleiche Methode unterschiedlich implementieren. Zum Beispiel:

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

Sehr schöne Erklärung. Ich bleibe jetzt bei den vier Loops, aber wenn es mehr als das ist, werde ich es versuchen! – Paul

+0

Eine Variation verwendet enums. Sie müssen das aufgerufene Objekt über einen Parameter im Methodenaufruf und nicht über den Konstruktor übergeben. –

5

Sie können Methoden in Arrays nicht in Java speichern, da Methoden in Java keine erstklassigen Objekte sind. Es ist ein Grund, warum manche Leute andere Sprachen wie Python, Scheme, etc. bevorzugen.

Das Problem besteht darin, eine Schnittstelle zu erstellen, die eine Methode enthält, und dann vier Klassen zu erstellen, die diese Schnittstelle implementieren - MoveRight, MoveLeft usw. .. Klassen. Dann können Sie Instanzen dieser Klassen in Ihrem Array speichern und sie auf die gleiche Weise aufrufen.

+0

+1 Ja, Schnittstellen sind die meiste Zeit besser als die Verwendung von Reflektion.:-) –

+0

java.lang.reflect.Method ist ein Objekt der ersten Klasse, aber ich stimme der allgemeinen Lösung zu, die Sie vorgestellt haben –

+1

@Brian: Ja, aber es ist ein Objekt, das die Methode darstellt, es ist eigentlich keine Methode pro -se. Sie können eine Instanz von Method nicht "aufrufen" (Sie rufen eine Methode für die Instanz auf). – Draemon

3

Ja, Sie können Methoden in Arrays unter Verwendung von Reflection speichern, es ist jedoch wahrscheinlich, dass Sie in dieser Situation wahrscheinlich nur polymorphism verwenden möchten.

Als Beispiel für Polymorphismus in Bezug auf Ihr Problem - sagen Sie eine Schnittstelle wie folgt erstellt:

public interface MoveCommand { 
    void move(); 
} 

Sie können dann Implementierungen wie folgt erstellen:

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

etc. für die anderen verschiebe Optionen. Sie könnten dann speichern diese in einer MoveCommand[] oder Sammlung wie ein List<MoveCommand> und iterieren dann das Array/Sammlung Aufruf move() auf jedem Element, zum Beispiel:

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(); 
     } 
    } 

} 

Polymorphismus ist sehr mächtig, und der oben ist ein sehr einfaches Beispiel für etwas namens Command Pattern. Genießen Sie den Rest Ihrer Wumpus World-Implementierung :)

4

Sie können solche Methoden nicht aufrufen. Aber Sie können mithilfe von Reflektion:

nur die erste Zeile ändern in der while-Schleife:

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

(Sie müssen erklären/ein paar Ausnahmen fangen)

Aber Sie würden besser Vermeiden Sie Reflexionen und verwenden Sie stattdessen die Command pattern.

+0

Warum ist es besser, Reflexion zu vermeiden? Ist die Reflektion zeitaufwendig oder die Erinnerung überwältigend? Die obigen Codes sehen sehr ordentlich aus. – byteBiter