Array mit verschiedenen Klassen

  • Themenstarter Themenstarter nopro
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
N

nopro

Gast
hallo!

ich möchte ein stragtegiespiel programmieren.
darin will ich ein array Einheit[] e=new Einheit[einheitenAnzahl]; erstellen.

aber Einheit soll nur die Superklasse der versch. einheitentypen sein.
zb: Superklasse: Einheit - Subklassen: Panzer, Soldat;
kann ich ein Array erstellen, in das ich Panzer UND Soldaten ablegen kann??

zur veranschaulichung, was ich meine:
dann könnte man schreiben;

Code:
if(e[x].getClass()==Soldat){
      e[x].laufNach(1,1);
}
if(e[x].getClass()==Panzer){
    e[x].fahrNach(1,1);
}

gibt es da eine eifache/gängige Lösung??
 
Soldat und Panzer könnten eine Methode "moveTo" haben anstatt "laufNach" und "fahrNach". Diese "moveTo"-Methode sollte abstract in Einheit deklariert sein.

Dann ist vollkommen egal, was für eine Einheit sich bewegen soll; das Objekt selbst (also Soldat oder Panzer) weiß, wie es eine Bewegung ausführen muss.
 
oberklasse[] array = new oberklasse[n];
oberklasse[0] = unterklasse1;
oberklasse[1] = unterklasse2;
oberklasse[2] = unterklasse1;
oberklasse[3] = unterklasse2;
//etc.....

Schleife zum durchlaufen
{
if(oberklasse[n] instanceof unterklasse1) ...
...


}


Du bekommst mit getClass ein Object der Klasse Class, dies kannst du nicht so einfach vergleichen.
Du könntest mit der toString() Methode dir den Namen der Klasse ausgeben lassen und diesen dann überprüfen
aber mit instanceof ist es wohl doch leichter.
Alternativ kannst du der Klasse Soldat und Panzer ein "Null"-interface implementieren aus dessen Typ du ein Array machst.
So benötigst du keine Oberklasse


EDIT: Huch da waren wohl welche Schneller.
 
Obwohl das nicht gerade OO-konform wäre. Besser dann so:

Code:
public abstract class Einheit {
  public abstract void bewegeNach (int x, int y);
}

public class Panzer extends Einheit {
  public void bewegeNach (int x, int y) {
    fahrNach(x, y);
  }

  public void fahrNach (int x, int y) {
    ...
  }
}

public class Soldat extends Einheit {
  public void bewegeNach (int x, int y) {
    laufNach(x, y);
  }

  public void laufNach (int x, int y) {
    ...
  }
}

EDIT: zu langsam :bae:

Gruß
Mag1c
 
Mag1c hat gesagt.:
Obwohl das nicht gerade OO-konform wäre. Besser dann so:

Code:
public abstract class Einheit {
  public abstract void bewegeNach (int x, int y);
}

public class Panzer extends Einheit {
  public void bewegeNach (int x, int y) {
    fahrNach(x, y);
  }

  public void fahrNach (int x, int y) {
    ...
  }
}

public class Soldat extends Einheit {
  public void bewegeNach (int x, int y) {
    laufNach(x, y);
  }

  public void laufNach (int x, int y) {
    ...
  }
}

EDIT: zu langsam :bae:

Gruß
Mag1c
Besser noch: Die laufNach bzw. fahrNach private zu machen (bzw. ganz darauf verzichten). Zwei Methoden, die das gleiche machen, da ist m.E. eine zuviel ;-) Also bei größeren Programmen kann das irgendwann zu Problem führen.
 
das ging ja schnell 😀 danke!
jetzt weiss ich auch, was ne abstract class ist...

aber ich hab noch ein problem:
ich will, dass die Subclasses auch verschiedene Parameter haben.
hier z.B. Panzer.höhe,breite Soldat.d (Durchmesser)

Code:
package twentyonedays;

public class Test {
	
	Einheit[] einheit=new Einheit[2];
	
	public static void main(){
		Test t=new Test();
		t.testit();
	}
	
	public Test() {
		super();
	}
	
	void testit(){
		einheit[0]=new Soldat();
		einheit[1]=new Panzer();
		System.out.println(einheit[0].d);
	}
	
	class Einheit{
		int x,y;
		Einheit(){
			super();
		}
	}
	
	class Soldat extends Einheit{
		int d;//durchmesser;
		Soldat(){
			super();
		}
	}

	class Panzer extends Einheit{
		int höhe,breite;
		Panzer(){
			super();
		}
	}
}

in meinem beispiel klappt das nicht.
gibt es dafür auch eine lösung??
 
PS: der Fehler komt in Zeile 19
"d can not be resolved or is not a field"
 
das is mir schon klar.
aber ich WILL ja, dass einheit[0] ein 'd' hat.
 
pack doch breite und höhe in einheit.
wenn es sich um einen durchmesser handelt, so ist breite = höhe
 
das spiel soll ja noch umfangreicher werden.
viele verschiedene arten von 'Einheit' werden dann viele verschiedene einheiten haben.

ich hab das jetzt so gelöst:
neben 'Einheit' gibt es noch eine Klasse 'EinheitInstanz'

Code:
package derSpieler;

import dieEinheiten.*;
import dieSteuerung.*;

public class EinheitInstanz {
	
	int typ;
	Gewehrmann gewehrmann;
	Panzer panzer;
	
	public EinheitInstanz(int typ) {
		super();
		this.typ=typ;
		if(typ==1){
			gewehrmann=new Gewehrmann();
		}
		if(typ==2){
			panzer=new Panzer();
		}
	}
	
	public Menü getMenü(){
		if(typ==1){
			return Gewehrmann.menü;
		}
		if(typ==2){
			return Fahrzeug.menü;
		}
		return new Menü();
	}
}

(jede Subclass kriegt ein static Menü, dass gezeigt wird, wenn eine einheit angeklickt ist)

ist zwar umständlich das für jede neue Subclass von 'Einheit' umzuprogrammieren,
aber praktisch das von aussen zu benutzen...
 
das ist schlecht gelöst, was du meinst ist eine EinheitenFactory
Code:
public class EinheitFactory{

   public static Einheit createEinheit(int typ) {
       Einheit result = null;
       switch(typ){
           case 0: result = new Fahrzeug(); break;
           case 1: result = new Panzer(); break;
           ....
           default: throw new IllegalArgumentException(); 
       }
       return new result;
   }
}
bei deiner Methode nutzt du die Vorteile von OO überhaupt nicht 🙂
 
Anonymous hat gesagt.:
da kommen doch wieder nur 'Einheit'en raus, oder?
Aber das sollte auch Sinn und Zweck sein im OO-Ansatz.
Wenn du zig verschiedene Dinge in ein Array packst, und dann jedesmal fragst: "Was bin ich für ein Objekt" und "Was muss ich denn jetzt machen" führt das zu zig if-else-Anweisungen, wo es gar nicht nötig wäre.
Überleg Dir, welche Eigenschaften eine Einheit haben muss und welche Methoden eine Einheit braucht.

Zu deinem Code: eine als 'abstract' definierte Methode getMenu gibt das jeweilige Menü der Einheit zurück; egal ob Panzer oder Soldat.
 
Moin,

also da kann ich meinen Vorschreibern nur beipflichten. Deine EinheitInstanz-Klasse ist eigentlich eine EinheitFactory (siehe Factory-Pattern). Wenn du für jede Einheit ein Menü haben willst, mach das genauso wie oben die Methode bewegeNach(...). Also abstrakte Methode getMenu() in der Klasse Einheit und in den abgeleiteten Klassen dann die Implementierung für den jeweiligen Typ.

Gruß
Mag1c
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben