# C++ typedef in Java umgehen wie? brauch hilfe



## 3Cyb3r (17. Januar 2011)

Hallo,

ich bin gerade ein Menü für ein Spiel zu implementieren. Ich gestaltee das ganze dynamisch, so das es auch für andere Spiele verwendbar ist. So etwas habe ich in C++ schon einmal gemacht hat super geklappt und so wollte ich mein Sourcecode nun einfach umschreiben. Das mit einfach war leider nichts, denn in Java gibt es nichts vergleichbares zu typedef (bitte keine Diskussion über den Sinn von typedef anfangen es macht bei Generics Sin!).

Mein kontretes Problem ist das ich durch typedef eine Variable Methode bekommen habe und nicht weiß wie ich dies in Java mache / umgehe.

Hier einmal mein C++ Code(alles vollständig damit man den Sinn erkennen kann^^):

```
namespace menu
{
class MenuEntry
{
protected:
  virtual void do_action() = 0;
  virtual std::string do_getName() const = 0;
  virtual std::string do_getDescription() const { return ""; }
public:
  void action() { do_action(); }
  std::string getName() const { return do_getName(); }
  std::string getDescription() const { return do_getDescription(); }
  virtual ~MenuEntry(){}
};

//Methode mit 0 Parametern
template<typename Class>
class MenuEntryMethod : public MenuEntry
{
public:
  typedef void (Class::*Method)();
private:
  Class* p;
  Method method;
  std::string name;
  
protected:
  void do_action()
  {
    (p->*method)();
  }
  std::string do_getName() const
  {
    return name;
  }
  
public:
  MenuEntryMethod(Class* p, Method method, std::string const& name)
  : p(p), method(method), name(name)
  {}
};

//Methode mit 2 Parametern
template<typename Class, typename Param1, typename Param2>
class MenuEntryMethodParam2 : public MenuEntry
{
public:
  typedef void (Class::*Method)(Param1, Param2);
private:
  Class* p;
  Method method;
  Param1 param1;
  Param2 param2;
  std::string name;
  
protected:
  void do_action()
  {
    (p->*method)(param1, param2);
  }
  std::string do_getName() const
  {
    return name;
  }
  
public:
  MenuEntryMethodParam2(Class* p, Method method, Param1 param1, Param2 param2,std::string const& name)
  : p(p), method(method), param1(param1), param2(param2), name(name)
  {}
};


//Vereinfach die Verwendung
template<typename Class>
MenuEntryMethod<Class>* makeMenuEntry(Class* p, void (Class::*method)(), std::string const& name)
{
  return new MenuEntryMethod<Class>(p, method, name);
}

template<typename Class, typename Param1, typename Param2>
MenuEntryMethodParam2<Class, Param1, Param2>* makeMenuEntry(Class* p, void (Class::*method)(Param1, Param2), Param1 param1, Param2 param2, std::string const& name)
{
  return new MenuEntryMethodParam2<Class, Param1, Param2>(p, method, param1, param2, name);
}

class Menu
{
protected:
  std::vector<MenuEntry*> entries;
  typedef std::vector<MenuEntry*>::iterator iterator;
  
  virtual void do_display() = 0;
  virtual void do_select() = 0;

public:
  virtual ~Menu()
  {
    std::for_each(entries.begin(), entries.end(), Delete());
  }
  
  void addEntry(MenuEntry* entry)
  {
    entries.push_back(entry);
  }
  
  void display() { do_display(); }
  void select() { do_select(); }
 
};
}
```

In meine Anwendung dann z.B.:

```
// Application heißt die Klasse in der dies ausgeführt wird

  menu::Menu* menu = new Menu();

  menu->addEntry(menu::makeMenuEntry(this, &Application::exit, "Exit"));
  menu->addEntry(menu::makeMenuEntry(this, &Application::startGame, PLAYER_HUMAN, PLAYER_AI,     "Start Game (Player    VS  Computer)"));
  menu->addEntry(menu::makeMenuEntry(this, &Application::startGame, PLAYER_AI, PLAYER_HUMAN,     "Start Game (Computer  VS  Player)"));
  menu->addEntry(menu::makeMenuEntry(this, &Application::startGame, PLAYER_HUMAN, PLAYER_HUMAN,  "Start Game (Player    VS  Player)"));
  menu->addEntry(menu::makeMenuEntry(this, &Application::startGame, PLAYER_AI, PLAYER_AI,        "Start Game (Computer  VS  Computer)"));
```

So hier mal mein momentaner Java Code:

```
public class MenuEntryMethod<T> extends MenuEntry {
	
	private T oclass;

        // geht nich da ich keine Methode als Attribut machen kann
	
	private String name;
	
	protected void do_action() {
		// geht ja nicht da das Attribut fehlt
		
	}
	
}
```


```
abstract public class MenuEntry {
	
	abstract protected void do_action();
	
	abstract protected String do_getName();
	
	protected final String do_getDescription() {
		return "";
	}
	
	public void action() {
		this.do_action();
	}
	
	public String getName() {
		return this.do_getName();
	}
	
	public String getDescription() {
		return this.do_getDescription();
	}

}
```


----------



## RoCMe (17. Januar 2011)

Hi!



> ```
> // geht nich da ich keine Methode als Attribut machen kann
> ...
> protected void do_action() {
> ...



Ich kann das Problem noch nicht ganz nachvollziehen, dein Ansatz sieht doch schon ganz vielversprechend aus?!
Wahrscheinlich verstehe ich von deinem C++ Code einfach zu wenig? Was genau fehlt dir denn noch?


----------



## 3Cyb3r (17. Januar 2011)

Ja es ist schwer zu erklären mit dem typedef. Das problem ist die typdef Zeile in MenuEntryMehtod dürch diese wird das ganze ja so schön dynamisch, dass ich später eine Liste mit Menüeinträgen erstellen kann undwenn ich einen Menüeintrag erstellen kann ich den Namen dessen und eine Funktion übergeben , welche bei Auswahl ausgeführt wird.


```
public:
  typedef void (Class::*Method)();
private:
  Method method;
```

Ich kann in  Java ja auch kein Pointer auf eine Funktion anlegen -.-


----------



## RoCMe (17. Januar 2011)

Ah, ich glaube ich begreife das "Problem" 

Was spricht gegen deinen 2. Ansatz mit der Abstrakten Klasse? In den Implementierungen kannst du jeweils die abstrakte action-Methode überschreiben.

Vielleicht gibt es auch mittels Generics einen schöneren Weg, aber ein Interface / abstrakte Klasse ist sicher möglich...


----------



## 3Cyb3r (17. Januar 2011)

Nein nichts zweiter ansatz das sind mehrere Klassen was ich am Anfang gepostet habe gehört alles zu meinem jetzigen Ansatz. Ich verwende schon Generics und will sie verwende, sowie abstrakte Klasse. 

Schau dir mal bitte den Code an beim ersten Post. Da wo ich die Menüeinträge initialisiere Das ist in einer ganz anderen Klasse und dort übergeben ich einen Pointer auf die Klasse wo die Methode drin steht, welche aufgerufen werden soll falls diese Menüpunkt ausgewählt werden soll und zusätzlich eine Referenz (so ähnlich wie ein Pointer) auf die zu aufrufende Methode.

Ich möchte eigl. so dynamisch bleiben wie ich jetzt bin, dass ich während der Laufzeit eine Methode einer Klasse zuweisen kann.

Ich dachte Java wäre SOO TOLL DYNAMISCH das ich nicht lache.


Ist denn hier niemand der auch C++ kann und mein Problem versteht?


----------



## wakoz (19. Januar 2011)

Eine Methode wirst du so (so wie du es in C++ Machst) nicht rein bekommen!
du kannst Konkrete Objekte Übergeben oder Daten Typen

Du kannst einen Generischen Menüeintrag erzeugen dem du zur Laufzeit (Programmstart) Strings zur Namensgebung und ein Listener Objekt mitgibst für die nötige Aktion bei Auswahl des Menüeintrages, bzw. benötigte Objekte die zur Ausführung des Menüeintrages benötigt werden.


----------

