Verwendung der Schnittstelle ClassT als Schlüssel, um konkrete Instanzwerte zu erhalten?

9

Ich habe den folgenden Testfall, bei dem die Werte von Map nicht abgerufen werden können:

%Vor%

Die erwartete Ausgabe war:

%Vor%

Die tatsächliche Ausgabe ist:

%Vor%

Nach meinem Verständnis ist der Fall "erwartet" fehlgeschlagen, weil B.class nicht gleich D.class ist, obwohl D class eine Implementierung der B Schnittstelle ist ... also der map.get(...) kann den Instanzwert für den zugeordneten Schlüssel nicht finden. (Korrigiere mich, wenn ich falsch liege.) Der obige Fall zeigt hoffentlich die Absicht und den "Geist" dahinter, was ich erreichen möchte.

Gibt es dafür eine gute / elegante Alternative, die aber auch den Geist dessen, was ich versucht habe, bewahrt?

Ich aktualisiere gerade Code, um die Enum-Typen zu ersetzen, die als 'offene Mengen' für Class<T> als Typ-Token verwendet werden, ähnlich wie Effektives Java, 2. Aufl., Punkt 29.

Wie von @CKing in einem Kommentar gefordert, wird unten der Teil des Buches zitiert, der meine Herangehensweise motiviert hat.

  

Der Client zeigt ein Class -Objekt an, wenn Sie Favoriten festlegen und abrufen.   Hier ist die API:

%Vor%      

Hier ist ein Beispielprogramm, das die Favorites Klasse ausübt, speichert,   Abrufen und Drucken eines Favoriten String , Integer und Class   Beispiel:

%Vor%      

Wie Sie vielleicht erwarten, druckt dieses Programm Java cafebabe Favorites .

Bitte haben Sie Verständnis dafür, dass das Buchbeispiel funktioniert, weil es die konkrete konkrete Klasse des Wertes verwendet (zB String.class für eine tatsächliche String und nicht irgendeine hypothetische abgeleitete Art von% co_de) %, usw.) Wie gesagt, dies motivierte einfach meinen Ansatz, um zu sehen, ob mein Testfall funktionieren würde, und jetzt suche ich nach einer Lösung oder Alternative, die den "Geist" dessen, was ich im Testfall machen wollte, respektiert.

    
ray 13.02.2017, 15:18
quelle

4 Antworten

0

Vielleicht nicht so elegant, aber Sie können Reflektion verwenden, um alle Werte, die von Key.class zugewiesen werden können, zu erhalten:

%Vor%     
Vlad Bochenin 13.02.2017 15:55
quelle
0

Wenn Interface-Klassenschlüssel zu konkreten Instanzen zugeordnet werden sollen, müssen Sie diese explizit zu Ihrer Map hinzufügen.

%Vor%     
Robert The Rebuilder 13.02.2017 15:57
quelle
0

Sie können Ihr Map.put() überschreiben, so dass jedes Mal, wenn jemand ein D.class setzt, es unter B.class eingibt. So:

%Vor%

Ausgabe:

%Vor%     
Matthew McPeak 13.02.2017 16:13
quelle
0

Sicher ist das Folgende keine elegante Lösung, aber es funktioniert unter Berücksichtigung Ihrer "einfachen" Hierarchie.

Er füllt einen Eintrag in der Map für jede Klasse in der Klassenhierarchie der Klassen der Werte. Dann können Sie mithilfe einer beliebigen Schnittstelle oder Klasse, die von den Werten implementiert wird, Werte aus der Map abrufen.

Wenn mehrere Werte die selbe Klasse / Schnittstelle implementieren, werden die Einträge überschrieben, aber Ihr Entwurf hat bereits diese Einschränkung.

%Vor%

Ausgabe:

%Vor%

Ehrlich gesagt, dieser Code ist schrecklich. Brauchen Sie wirklich eine solche Funktion?

    
Emmanuel Guiton 13.02.2017 17:01
quelle

Tags und Links