# Methoden per Übergabe eines "Methodennamen-Strings&quot



## jeremia (6. Okt 2004)

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 


```
AudioPlayer.(Stringinhalt)()
```

Gibt's sowas?

Vielen Dank,
Jeremia


----------



## Guest (6. Okt 2004)

Sorry, jetzt habe ich wohl im falschen Topic gepostet.


----------



## foobar (6. Okt 2004)

Am einfachsten lässt dich sowas über Interfaces realisieren:

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


----------



## Beni (6. Okt 2004)

Und verschoben 

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


```
Class clazz = AudioPlayer.class;

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

method.invoke( irgendeinAudioPlayer, new Object[0] );
```


----------



## Guest (6. Okt 2004)

Supi, Leute!

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

Jeremia


----------



## Roar (6. Okt 2004)

also ich muss schon sagen dass die lösung mit den interfaces um einiges sauberer ist :?


----------



## Beni (6. Okt 2004)

Ja Roar, da hast du sicher recht. Aber dann braucht er trotzdem ein paar if's...


----------



## foobar (6. Okt 2004)

> also ich muss schon sagen dass die lösung mit den interfaces um einiges sauberer ist


Und um einiges schneller


----------



## dotlens (13. Okt 2004)

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?


----------



## foobar (13. Okt 2004)

> 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?


----------



## dotlens (13. Okt 2004)

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?


----------



## foobar (13. Okt 2004)

Poste mal bitte den Code, ich weiß nicht genau was du machen willst.


----------



## dotlens (13. Okt 2004)

hier das Grundsätzliche (eigentlich nur add methode wichtig):

```
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:

```
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:

```
data.addKopierenMethode(new Action() {

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

ach ja und das Interface:

```
interface Action{
	void invoke();
}
```

danke


----------



## foobar (13. Okt 2004)

Dann mußt du ein zweites Interface anlegen, womit du einen Parameter entgegen nehmen kannst.

```
interface ParameterAction()
{
  void invoke(Object o);
}
```


```
data.addKopierenMethode(new Action() 
{
   public void invoke(Object o) 
   {
          controllerKopieren.kopierenAlleFormen( o ); 
    }
});
```


----------



## dotlens (13. Okt 2004)

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...


----------



## dotlens (13. Okt 2004)

irgendwie funzt das aber nicht:

mein code:

```
data.addKopierenMethode(new ActionMitObj(String "test) {

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

mein zusätzliches Interface:

```
interface ActionMitObj{
	void invoke(String string);
}
```
meine zusätzliche add Methode:

```
public void addKopierenMethode(ActionMitObj methode){
		methoden.addElement(methode);
	}
```

was mach ich denn falsch?


----------



## dotlens (13. Okt 2004)

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....


----------



## foobar (13. Okt 2004)

```
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.


----------



## dotlens (14. Okt 2004)

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


----------



## foobar (14. Okt 2004)

> 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.

```
abstract class DefaultAction implements Action
{
    protected Object param;
    public DefaultAction(Object param)
    {
        this.param = param;
    }
}
```


```
data.addKopierenMethode(new DefaultAction("test")
{
    public void invoke()
    {
       System.out.println("Method: invoke Parameter: " + this.param );
        // do something
    }
});
```


----------



## dotlens (14. Okt 2004)

WOW! Du bist mein gott 

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

danke vielmals


----------

