# Unterscheidung von Sprites mit verschiedenen Eigenschaften



## Dagobert (9. Sep 2009)

Guten Tag, alle zusammen.
Ich beschäftige mich gerade mal wieder mit einem kleinem Problem:

Ich habe eine Klasse Sprite, diese ist das Grundgerüst für fast alles Leben was zu finden ist. Also Kreaturen(weiter aufgeteilt in weitere Klassen: Elben, Menschen, ...), Häuser, Zäune und auch kleines Krabbelzeug (als deko).
Jetzt komme ich zu folgendem Problem. Ich will im späteren Verlauf sowohl Häuser auch als Creaturen/Einheiten anklicken können. Dabei sollen sie verschiedene Funktionen haben. Häuser sollen z.B. Einheiten schutz bieten, im Gegensatz sollte man Einheiten bewegen können, ein Haus nicht richtig ? 
Und dort liegt der Hund begraben.
Wie bekomme ich die Unterscheidung hin. Die Sprite-Klasse hat ja nicht die nötigen Methoden wie z.B. moveTo(Point p). Diese wird erst bei der Creatur-Klasse hinzugefügt.
Jedoch komme ich dann mit meinem Verfahren nicht wieder an die Methode heran:

Auf der Karte habe ich ein Liste wo alle Sprites abgespeichert werden:

```
private LinkedList<Sprite> sprites;
```

Dann habe ich ein Speicher für den aktuellen "aktiven"/angeklickten Sprite:

```
...
private Sprite selectSprite;
...
```
Wenn jetzt die Maus irgendwo hinklickt, soll die Figur sich nach dort bewegen:

```
...
if(select.isPressed()){
selectSprite.moveTo(moveTo);
}
...
```

Hier nochmal meine Herachie:


> Sprite <- Creature (abstract) <- Elbbogenschütze
> Spite <- Gebäude (abstract) <- div. Gebäude



Wo muss meine moveTo()-Methode hin?
Ich hab versucht den currentSprite nach Creatur zu casten, aber dies geht ja nicht da es eine abstracte Klasse ist.

mfg. Dagobert


----------



## Quaxli (9. Sep 2009)

Du könntest mit instanceof arbeiten, aber das ist in meinen Augen keine sehr schöne Lösung. Hier mal ein Beispiel:


```
public class Test {

	public static void main(String[] args) {
		new Test();
	}

	public Test() {
    Langohr elf = new Langohr();
    testClass(elf);
	}

	public void testClass(Sprite s){
		
		if(s instanceof Creature){
			System.out.println("Typ = Creature");
			((Creature) s).check();
		}
		
	}
	
}

class Sprite {

}

class Creature extends Sprite {

	public void check(){
		System.out.println("kuckuck");
	}
	
}

class Langohr extends Creature {

}
```


Aber das sieht jetzt schon ein bißchen chaotisch aus. Ich würde mir erstmal über die Klassenhierarchie Gedanken machen. Wenn es jetzt erst mal nur um die Bewegung geht, würde ich die Gebäude- und Creature-Klassen weglassen (diese Mischung von Deutsch und Englisch übrigens auch).
Du könntest z. B. eine Instanzvariable vom typ boolean definieren die aussagt, ob ein Objekt bewegt werden darf oder nicht und das Ganze darüber steuern. Dann hättest Du für dieses Beispiel eine Klasse weniger. Inwieweit das Sinn macht, kann ich aber nur eingeschränkt sagen, da ich nicht weiß, was Du vorhast und was noch so abgebildet werden soll.


----------



## andre111 (9. Sep 2009)

Oder halt statt einer Liste 2 Listen verwenden, in einer die statischen Objekte speichern (Gebäude, ...) und in der anderen alles was bewegt werden kann.


----------



## EgonOlsen (10. Sep 2009)

Flags oder Typisierungen per isXXX() sind nicht "besser" als instanceof. Genau genommen sind sie sogar schlechter. Wann immer instanceof nötig ist (wobei ich jetzt nicht sage, dass es prinzipiell schlecht oder böse ist...), liegt das zumeist daran, dass die es benutzende Klasse sonst nicht entscheiden kann, welche Aktionen mit welchen Objekten durchgeführt werden sollen. Das ist hier ja auch so. Als Ersatz bietet sich eigentlich immer eine Variante von Double-Dispatch an. Man übergibt die Verantwortung für das, was zu tun ist damit an das Objekt selber und das gibt (weil es zumeist nicht alles selber machen kann) die Kontrolle wieder zurück. Vorteil ist, dass das Objekt selber immer weiß, was zu tun ist. Man benötigt hier kein instanceof mehr, denn die Instanz selber entscheidet, was zu machen ist. Ein Beispiel:

Aus sowas:

```
public class NDD {

	public static void main(String[] args) {
		House h = new House();
		Creature c = new Creature();
		StaticStuff s = new StaticStuff();

		Dispatcher dis = new Dispatcher();
		dis.action(h);
		dis.action(c);
		dis.action(s);
	}
}

interface Entity {
}

class Dispatcher {

	void action(Entity e) {
		if (e instanceof Creature) {
			move(e);
		}
		if (e instanceof House) {
			select(e);
		}
		if (e instanceof StaticStuff) {
			// nix...
		}
	}

	void move(Entity e) {
		System.out.println("Moved!");
	}

	void select(Entity e) {
		System.out.println("Selected!");
	}
}

class Creature implements Entity {
}

class House implements Entity {
}

class StaticStuff implements Entity {
}
```


wird dadurch sowas:

```
public class DD {

	public static void main(String[] args) {
		House h = new House();
		Creature c = new Creature();
		StaticStuff s = new StaticStuff();

		Dispatcher dis = new Dispatcher();

		h.action(dis);
		c.action(dis);
		s.action(dis);
	}
}

interface Entity {
	void action(Dispatcher d);
}

class Dispatcher {

	Dispatcher() {
	}

	void move(Entity e) {
		System.out.println("Moved!");
	}

	void select(Entity e) {
		System.out.println("Selected!");
	}
}

class Creature implements Entity {
	public void action(Dispatcher d) {
		// Bewegen
		d.move(this);
	}
}

class House implements Entity {
	public void action(Dispatcher d) {
		// Auswahl
		d.select(this);
	}
}

class StaticStuff implements Entity {
	public void action(Dispatcher d) {
		// Mache nichts...
	}
}
```


----------



## Dagobert (11. Sep 2009)

Danke für eure Hilfe (mal wieder ).
Ich habe mich jetzt erstmal für instanceof entschieden, da ich daran auch als erstes gedacht haben, aber auch daran gedacht habe das eine Methode mit weniger Aufwand gibt.

Danke schön nochmal =)

mfg. Dagobert

PS: Ich möchte gerne auch auf meine anderen offenen Fragen hinweisen  ^^


----------

