Methoden per Übergabe eines "Methodennamen-Strings&quot

  • Themenstarter Themenstarter jeremia
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
J

jeremia

Gast
Tach, Leute!

Ich bin erst seit einem halben Jahr dabei, mir Java draufzuschaffen, insofern hoffe ich keine allzu blöde Frage zu stellen, aber ich hab's im Netz einfach nirgendwo gefunden:

Ich möchte, je nachdem, was in einem String steht, verschiedene Methoden eines Objektes aufrufen. Sagen wir mal, mein Objekt (ein AudioPlayer) hat die Methoden "play" und "stop".

Jetzt möchte ich, dass ein anderes Objekt, je nachdem, ob in einem String "play" oder "stop" steht, die Methode AudioPlayer.play() bzw. AudioPlayer.stop() aufrufen, möchte aber nicht per if/else jede Möglichkeit von Hand programmieren, sondern dass einfach die Methode, die dem Stringinhalt entspricht, aufgerufen wird. Sprich, ich suche eine Konstruktion à la

Code:
AudioPlayer.(Stringinhalt)()

Gibt's sowas?

Vielen Dank,
Jeremia
 
Am einfachsten lässt dich sowas über Interfaces realisieren:
Code:
package demos.dispatcher;
import java.util.HashMap;

public class InterfaceDispatcher
{
	private HashMap data;
	public InterfaceDispatcher()
	{
		this.data = new HashMap();
	}
	
	public void invoke(String key)
	{
		((Action)this.data.get(key)).invoke();
	}
	
	public void addAction(String key, Action action)
	{
		this.data.put(key, action);
	}

	public void removeAction(String key)
	{
		this.data.remove(key);
	}

	public static void main(String[] args)
	{
		InterfaceDispatcher dispatcher = new InterfaceDispatcher();
		dispatcher.addAction("action1", new Action(){   public void invoke(){   new MyClass().doSomething();  }});
		dispatcher.addAction("action2", new Action(){ 	 public void invoke(){   new MyOtherClass().doSomethingElse();   }});
		dispatcher.addAction("action3", new YetAnotherClass());
		dispatcher.invoke("action3");
	}
}


//##########################################################################################
//##########################################################################################


interface Action
{
	void invoke();
}

// ##########################################################################################
//##########################################################################################

class MyClass
{
	public void doSomething()
	{
		System.out.println("Class "+ this.getClass() + " doSomething()");
	}
}

//##########################################################################################
//##########################################################################################

class MyOtherClass
{
	public void doSomethingElse()
	{
		System.out.println("Class "+ this.getClass() + " doSomethingElse()");
	}
}


//##########################################################################################
//##########################################################################################


class YetAnotherClass implements Action
{
	public void doSomethingCompletelyDifferent()
	{
		System.out.println("Class "+ this.getClass() + " doSomethingCompletelyDifferent()");
	}

	public void invoke()
	{
		this.doSomethingCompletelyDifferent();
	}
}
 
Und verschoben 😀

Sowas kann man über die Klasse "Class" machen.

Code:
Class clazz = AudioPlayer.class;

Method method = clazz.getDeclaredMethod( "stop", new Class[0] );

method.invoke( irgendeinAudioPlayer, new Object[0] );
 
Supi, Leute!

Ich muss mir das jetzt beides erst mal in Ruhe angucken, aber schon mal vielen Dank!

Jeremia
 
also ich muss schon sagen dass die lösung mit den interfaces um einiges sauberer ist :?
 
Ja Roar, da hast du sicher recht. Aber dann braucht er trotzdem ein paar if's...
 
wie kann man denn eine Methode hinzufügen, die einen Parameter hat? habs versucht, aber man kann keine Variablen in inneren Klassen einbauen, die nicht final sind.

muss ich dass dann über ein Modell lösen? und die Daten dann beim aufrufen der Methode holen, oder geht das einfacher?
 
wie kann man denn eine Methode hinzufügen, die einen Parameter hat? habs versucht, aber man kann keine Variablen in inneren Klassen einbauen, die nicht final sind.

muss ich dass dann über ein Modell lösen? und die Daten dann beim aufrufen der Methode holen, oder geht das einfacher?
Wo willst du eine Methode hinzufügen?
 
naja hab das wie oben gezeigt gemacht. meine methoden/actions hab ich in einem array gespeichert und beim letzten klick des Benutzers wird dann alles ausgeführt.
hab aber Probleme mit mehtoden, welche Parameter haben, weil in inneren Klassen die Variablen nicht erkannt werden....

soll ich den code posten oder war das verständlich?
 
hier das Grundsätzliche (eigentlich nur add methode wichtig):
Code:
	private Vector methoden = new Vector();

	public void addKopierenMethode(Action methode){
		methoden.addElement(methode);
	}
	public void removeKopierenMethoden(){
		methoden.removeAllElements();
	}
	public Action[] getKopierenMethoden(){
		//Enumeration methodenEnumeration = methoden.elements();
		Action[] methodenArray = new Action[methoden.size()];
		for(int i = 0; i < methoden.size(); i++)
			methodenArray[i] = (Action)methoden.elementAt(i);
		return methodenArray;
	}
hier füre ich hinzu:
Code:
	public void kopierenAlle(int welche) {
		switch (welche) {
			case 2:
				data.addKopierenMethode(new Action() {

					public void invoke() {
						controllerKopieren.kopierenAlleSymbole();
					}
				});
				data.addKopierenMethode(new Action() {

					public void invoke() {
						controllerKopieren.kopierenAlleFormen();
					}
				});
			break;
			case 11:
				data.addKopierenMethode(new Action() {

					public void invoke() {
						controllerKopieren.kopierenAlleSymbole();
					}
				});
			break;
			case 12:
				data.addKopierenMethode(new Action() {

					public void invoke() {
						controllerKopieren.kopierenAlleFormen();
					}
				});
			break;
		}
	}

eigentlich möchte ich aber die methoden so hinzufügen:
Code:
				data.addKopierenMethode(new Action() {

					public void invoke() {
						controllerKopieren.kopierenAlleFormen(eineVariable);//<------- Das wichtige
					}
				});

ach ja und das Interface:
Code:
interface Action{
	void invoke();
}

danke
 
Dann mußt du ein zweites Interface anlegen, womit du einen Parameter entgegen nehmen kannst.
Code:
interface ParameterAction()
{
  void invoke(Object o);
}

Code:
data.addKopierenMethode(new Action() 
{
   public void invoke(Object o) 
   {
          controllerKopieren.kopierenAlleFormen( o ); 
    }
});
 
da sieht man wieder, dass ich das mit dem interface nicht verstanden habe, aber mein chef findet:
"mach noch n paar tools, kannst nachher wieder etwas lernen!" 😉

danke...
 
irgendwie funzt das aber nicht:

mein code:
Code:
data.addKopierenMethode(new ActionMitObj(String "test) {

					public void invoke() {
						controllerKopieren.kopierenEinzelneSymbole("test");
					}
				});

mein zusätzliches Interface:
Code:
interface ActionMitObj{
	void invoke(String string);
}
meine zusätzliche add Methode:
Code:
	public void addKopierenMethode(ActionMitObj methode){
		methoden.addElement(methode);
	}

was mach ich denn falsch?
 
bitte gebt mir doch eine antwort. auch wenn ihr nicht sicher seid. hab keine ahnung wie ich das machen soll. und in der API hab ich auch nichts gefunden....
 
Code:
 data.addKopierenMethode(new ActionMitObj(String "test) {

               public void invoke() {
                  controllerKopieren.kopierenEinzelneSymbole("test");
               }
            });
Hier übergibst du den Wert an den Konstruktor von ActionMitObj, anstatt die Methode invoke mit dem Parameter aufzurufen.
 
danke für die Mühe, hat auch fast geklappt. aber dann hat das aufrufen mit invoke() nicht mehr geklapt. ich hätte im den Parameter nochmals übergeben müssen, hab in jedoch nirgends mehr gehabt.

also hab ich das ganze über ein DatenModel gelöst, in welches ich die Parameter speichere und wieder auslese. nicht gerad professionel, aber wenn ichs nicht besser kann 🙁
 
danke für die Mühe, hat auch fast geklappt. aber dann hat das aufrufen mit invoke() nicht mehr geklapt. ich hätte im den Parameter nochmals übergeben müssen, hab in jedoch nirgends mehr gehabt.
So war das auch gedacht ;-). Falls du den Parameter nicht beim Aufruf mitgeben willst, erstellst du dir eben eine abstrakte Klasse die das ActionInterface implementiert und im Konstruktor einen Parameter entgegennimmt.
Code:
abstract class DefaultAction implements Action
{
    protected Object param;
    public DefaultAction(Object param)
    {
        this.param = param;
    }
}

Code:
 data.addKopierenMethode(new DefaultAction("test")
{
    public void invoke()
    {
       System.out.println("Method: invoke Parameter: " + this.param );
        // do something
    }
});
 
WOW! Du bist mein gott 😉

shat endlich geklappt. und die idee ist wirklich gut! versteh sie sogar 😉

danke vielmals
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben