2016-06-10 24 views
3

Die Wahl habe ich eine Basisklasse Feind und verschiedene Unterklassen aufgerufen, die vom Typ Feind sind wie BigEnemy, LazerEnemy, AvoidingEnemy usw.eine Unterklasse ohne switch-Anweisung in Java

ich eine Ausbildung Klasse, deren Zweck ist die Schaffung spezialisierte Formationen von Feinden wie Linie, Gitter, Pyramide.

Ich möchte Bildung als Parameter aufnehmen, welche Art von Unterklasse des Feindes ich erstellen möchte.

Formation f = new Formation("LazerEnemy","triangle", 4); // makes a triangle formation of lazer enmies 
Formation f = new Formation("BigEnemy","line", 10); // makes a line of big enemies 

Derzeit würde ich etwas tun, wie eine Zeichenfolge enemyType genannt passieren (oder es könnte nur eine ganze Zahl sein und Aussagen schalen), aber da ich so viele Gegnertypen habe ich mich gefragt, ob es eine sauberere war Möglichkeit, den Typ des Objekts zu übergeben, das ich instanziieren möchte, das keine switch-Anweisung verwenden muss.

Vielleicht hat das etwas mit Factory und this Frage zu tun, aber ich verstehe es nicht ganz.

Dank

+0

Warum können Sie nicht direkt eine 'neue LazerEnemy passieren()' oder 'neue BigEnemy()', mit 'Formation' Konstruktor ein' Enemy' nehmen als erster Parameter? – Tunaki

+0

Sie haben drei Möglichkeiten, 1) bedingten Verzweigungsschalter oder wenn-sonst verwenden, 2) Reflektion verwenden und in der Klasse z. LazerEnemy.class, 3) haben unterschiedliche Fabrikmethoden, z.B. Formation.createBigEnemy ("line", 10); – bhspencer

+0

@Tunaki Also sagst du, in einem Unterklasse-Objekt als ein Parameter zu Bildung wie Formation (neue LazerEnemy(), "Pyramide", 4) übergeben und dann Formation Konstruktor tun was? Ich muss mehrere neue Feindtypen erstellen. Formation (Feind e, String ftype, int-Nummer) {}. Ich muss jetzt mehrere Gegner erschaffen. Sollte ich e klonen? – user3772547

Antwort

0

Sie durch die Schaffung eines Feindes Factory Schnittstelle lösen sollte, und dann bestimmte Instanzen EnemyFactories für alle Ihre Gegnertypen. Dann verwenden Sie es wie

Formation f = new Formation(LazerEnemyFactory,FormationShape, 4); 
+1

Dies sollte ein Kommentar sein, keine Antwort. – bhspencer

+1

@bhspencer Warum? Es beantwortet die Frage, nicht die Art und Weise, wie es gefragt wurde. –

+0

Ich stimme zu und mache etwas Arbeit, um deine Antwort beschreibender zu machen. Ich weiß, was Sie versuchen, ihm zu sagen, aber es gibt viele Java-Fabriken, warum nicht zeigen, ein nahes zu relevanten Beispiel wie ... [Implementing-Factory-Design-Muster-in-Java] (http://howtodoinjava.com/ Design Patterns/Design/Implementing-Factory-Design-Muster-in-Java /) – Underbalanced

1

Es gibt viele Möglichkeiten, dies zu beheben. Einer davon benutzt Dependency Inversion principle. I.e. der Anrufer des new Formation() Konstruktor kann die Feinde schaffen zu:

Formation f1 = new Formation(new LazerEnemy(), "triangle", 4); 
Formation f2 = new Formation(new BigEnemy(), "line", 10); 

Wenn diese Feinde lange Konstrukteure haben, dann könnten Sie ein Dependency Injection-Framework verwenden. Google guice ist relativ einfach einzurichten.

-1

Ich würde wahrscheinlich mit einer Fabrikmethode gehen.

dieser Pseudocode könnte ein wenig rau an den Rändern sein, aber es sollte den Punkt über den Punkt bekommen.

4

Wenn ich richtig verstehe, muss der Formationskonstruktor in der Lage sein, mehrere Instanzen eines bestimmten Typs von Feind zu erstellen. Statt den Typen des Feindes als String oder als eine Klasse von geben, sollten Sie geben einfach der Bildung einen Weg um die Feinde zu schaffen, dh eine Fabrik oder Lieferanten von Feinden:

public clas Formation<E extends Enemy> { 

    // we'll store them in a list 
    private List<T> enemies; 

    public Formation(Supplier<E> enemySupplier, int count) { 
     enemies = new ArrayList<>(); 
     for (int i = 0; i < count; i++) { 
      enemies.add(enemySupplier.get()); 
     } 
    } 
} 

Sie können dann eine Formation von LazerEnemy auf diese Weise erstellen, wenn LazerEnemy einen Konstruktor ohne Argumente hat:

Formation<LazerEnemy> f = new Formation<>(LazerEnemy::new, 10); 

Angenommen, der LazerEnemy Konstruktor eine Stärke für seine lazer braucht, würden Sie verwenden

Kurz gesagt, lassen Sie den Anrufer entscheiden und spezifizieren, wie die Feinde in der Formation erstellt werden müssen, anstatt die Formation zu zwingen, zu wissen, wie man alle Arten von Feinden erzeugt.

+0

Ja, das ist ein guter Weg, es zu tun: Es entkoppelt die Logik. Eine 'Formation' hat die Verantwortung, die Bildung von Feinden zu schaffen. Es hat nicht die Verantwortung, die Feinde zu erschaffen; Ziel ist es, sie in eine richtige Formation zu bringen. – Tunaki

+0

Ein paar Fragen. An der Spitze hast du Formation . Ich benutze Generika, wenn ich solche Arraylisten verwende, aber was passiert hier? Was ist E? Zweite .. Ist Lieferant eine Klasse, die ich machen muss? Wie sieht es aus? Liefert die Methode get ein neues Feindobjekt zurück? drittens habe ich den doppelten Doppelpunktoperator vorher gesehen, aber ich weiß nicht, was es bedeutet. Ich benutze Java 8 momentan nicht. Habe den Pfeil vorher noch nicht gesehen. – user3772547

+0

E ist die Art von Feinden in der Formation. Wenn Sie es nicht brauchen, können Sie Ihre Klasse nicht generisch machen. Aber wenn Sie Feinde aus Ihrer Formation herausholen müssen und wissen, welchen tatsächlichen Typ sie haben, sollte Ihr Typ generisch sein. Es macht Sinn: Wenn ich richtig verstehe, ist eine Formation eine Ansammlung von Feinden, genau wie eine Liste. E ist die Art von Feinden, die in der Formation enthalten sind. [Lieferant] (https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html) ist eine Schnittstelle des JDK. Sie könnten einen anderen machen, aber der Lieferant passt gut. –

2

Sie können einen Typ an Methode als Argument übergeben.

Formation f = new Formation(LazerEnemy.class, Shape.LINE, 4) 

public formation(Class<? extends Enemy> enemyType, Shape shape, int num) { 
    Enemy enemy1 = enemyType.newInstance(); 
    ... 
} 

Sie benötigen ein try obwohl

+1

Ich habe das geschrieben, als du es gepostet hast! Vielen Dank :). Er würde auch eine Schleife und einen Weg brauchen, die Feinde zu sammeln. Er könnte eine statische Klassenfabrik in der Enemy-Klasse bauen, die einen Feind oder Feinde zurückgibt. Außerdem muss er möglicherweise die Constructor-Methode von newInstance verwenden, wenn er Parameter an die Feinde weitergeben möchte. – Underbalanced