instanceof zu großzügig

hpvw

Erfahrenes Mitglied
Hallo Forumsgemeinde,
endlich habe ich mal wieder eine Frage.

Umgebung des Problems
Ich glaube, es ist nicht ganz so wichtig, aber ich will trotzdem mal etwas detaillierter schreiben, um was es geht. Wer das nicht lesen will, kann gleich unten beim Problem weiterlesen.

Ich schreibe gerade einen Zufallszahlenstrom, der einen sog. Transformer übergeben bekommt, also eine Klasse, die eine Funktion enthält, welche die [0,1[ verteilte Zufallszahl in eine andere Verteilung (z.B. Gleichverteilung auf einem anderen Interval, dasselbe mit ganzen Zahlen, Diskrete Verteilungen, später wohl auch normalverteilt) transformiert.
Einige der Transformer erben nicht nur vom abstrakten Transformer, sondern von Implementierungen desselben.

Nun bin ich dabei, die entsprechenden visuellen Komponenten (Swing) zu erstellen, mit denen der User die Transformer einstellen kann. Dazu gibt es eine JComboBox, in der die entsprechenden Verteilungen aufgeführt sind. Je nach Auswahl in der Combobox wird in der visuellen Komponente ein entsprechender Transformer erstellt und das dazu gehörige Parameter-Auswahl-JPanel (jeweils eigene Klassen) unter der Combobox angezeigt.
Dieses Panel soll jedoch nur aktualisiert werden, wenn sich die Auswahl in der ComboBox auch tatsächlich geändert hat und nicht, wenn diese nur aufgeklappt und durch Klick auf das aktive Element wieder geschlossen wird.

Dazu wird im ActionListener die neue Auswahl geprüft und, ob der noch vorhandene Transformer keine Instanz des ausgewählten Transformer ist. In dem Fall wird der Transformer neu erstellt und das entsprechende JPanel erzeugt.

Problem
Wenn eine Klasse von einer anderen erbt (Z.B. B erbt von A) gibt folgender Code true aus:
Code:
A a = new A();
A b = new B(); //B extends A
if (b instanceof A) {
    System.out.println("true");
}
Nun suche ich eine Möglichkeit, so zu vergleichen, dass nur als A initialisierte Variablen auch als zugehörig zur Klasse A erkannt werden und Erben der Klasse A nicht als zugehörig erkannt werden.
Im Moment ist das noch recht übersichtlich und ich helfe mir damit, dass ich mit und verknüpft alle Erben auschließe. Auf Dauer halte ich das jedoch für keine geeignete Lösung, da man für jeden Erben, der hinzukommt die Abfragen nach allen Superklassen bearbeiten muss und dabei sehr schnell Fehler passieren können, insbesondere, wenn es über mehrere Hierarchiestufen geht.

Wieder etwas weiter weg vom Problem
Ich habe auch schon überlegt, jeden Erben von Transformer das entsprechende Parameter-Auswahl-Panel selbst erzeugen zu lassen. Jedoch wiederstrebt mir das etwas, da erstens nicht sicher ist, ob es auf ewig bei Swing bleibt und ich zweitens nicht viel von der Vermischung von Algorithmen und Visualisierung halte.
Der konsequente Schritt wäre entsprechende Swing-, bzw. AWT- oder SWT-Fabriken oder -Erbauer zu implementieren. Aber damit kann man wieder bei "Problem" nachlesen, den das bedingt auch, die Klassenzugehörigkeit der Instanz zu vergleichen und die Erben auszuschliessen.

Hat jemand eine Idee, wie sich das lösen lässt, ohne auf alle Erben einzeln Rücksicht nehmen zu müssen?
Vielleicht habe ich zur Zeit auch nur einen totalen Black-Out und sehe die einfachste aller Lösungen nicht.

Ich hoffe ihr habt mein Problem verstanden und Danke für eure Ideen.

Gruß hpvw
 
Hallo!

Suchst du sowas:

Code:
/**
 * 
 */
package de.tutorials;

/**
 * @author Tom
 *
 */
public class A {

}

/**
 * 
 */
package de.tutorials;

/**
 * @author Tom
 *
 */
public class B extends A{

}

Code:
/**
 * 
 */
package de.tutorials;

/**
 * @author Tom
 */
public class TestAB {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		A a = new A();
		A b = new B();

		System.out.println("a instanceof A: " + (a instanceof A));
		System.out.println("b instanceof A: " + (b instanceof A));

		System.out.println("a.getClass().equals(A.class): "
				+ a.getClass().equals(A.class));
		System.out.println("b.getClass().equals(A.class): "
				+ b.getClass().equals(A.class));
	}

}

Ansonsten würde ich dir das Strategy Pattern für die Implementierung der unterschiedlichen Verteilungsfunktionen...

Gruß Tom
 
Hi Tom,
Irgendwie habe ich mir gedacht, dass Du das löst :D
Dankeschön, mit getClass geht's, vielen Dank.

Ich habe eben noch mal in mein Gamma-Buch geschaut und bin mir ziemlich sicher, das ich die Verteilungen bereits als Strategy Pattern implementiert habe. Ohne den Namen des Pattern noch zu wissen, hatte ich das Pattern zumindest inhaltlich im Kopf, als ich angefangen habe. Mein RandomStream ist der Kontext, der Transformer ist die Strategie und seine Erben sind die konkreten Strategien (wie Du siehst, habe ich die dt. Übersetzung).
Du meintest doch die Algorithmen an sich und nicht die Verbindung zur Visualisierung?
Dazu wollte ich nämlich einen Builder Pattern nehmen. Aber das kommt erst, wenn das aktuelle Projekt mit Hilfsmitteln (siehe "Umgebung des Problems") gelöst ist. Der Abgabetermin rückt immer näher, aber ich bemühe mich soweit wie möglich auch für die Visualisierung schon mal Code zu schreiben, den ich hinterher in einem pattern-orienterten Package wiederverwenden kann. Mit den Verteilungen selbst sehe ich da keine Probleme.

Vielen Dank noch mal
hpvw
 
Zurück