public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
System.out.println("Dont go here please");
}
public void thisMethod(SpecificFoo specificFoo) {
// not into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}
Rufnummer:
SomeClass myClass = new SomeClass();
SomeOlderClass olderClass = new SomeOlderClass(myClass);
Ich habe eine Schnittstelle ( SomeInterface
), die mehrere Klassen aufrufen (z. B. SomeOlderClass
). Ich habe eine Klasse, die die Schnittstelle implementiert, aber ich möchte typsichere Operationen an den spezifischen Implementierungen durchführen, die an die generische Schnittstelle übergeben werden.
Wie im obigen Code gezeigt, möchte ich eigentlich eine weitere Methode erstellen, die dem spezifischen Typ entspricht, der an die Schnittstelle übergeben wird. Das funktioniert aber nicht. Ich nehme an, dass dies daran liegt, dass der aufrufende Code nur die Schnittstelle kennt, nicht aber die Implementierung mit den spezifischeren Methoden (auch wenn SpecificFoo implements Foo
)
Wie kann ich dies also auf die eleganteste Weise tun? Ich kann den Code zum Laufen bringen, indem ich eine if-Anweisung in die Klasse einfüge, die die Schnittstelle implementiert ( SomeClass
) :
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
if ( someKindOfFoo.getClass().equals(SpecificFoo.class) )
thisMethod(SpecificFoo.class.cast(someKindOfFoo));
else
System.out.println("Dont go here please");
}
Dies ist jedoch nicht elegant, da ich jedes Mal, wenn ich eine neue Art von Foo hinzufüge, if-Anweisungen hinzufügen muss. Und das könnte ich vergessen.
Die andere Möglichkeit besteht darin, Folgendes hinzuzufügen SpecificFoo
zum SomeInterface
und lassen Sie den Compiler mich daran erinnern, dass ich Implementierungen in SomeClass
. Das Problem dabei ist, dass ich am Ende eine ganze Menge Code hinzufügen muss. (Wenn jemand anderes die Schnittstelle implementiert, muss er auch die neue Methode sowie alle Tests implementieren).
Es scheint eine weitere Option zu geben, die ich vermisse, da Foo
y SpecificFoo
verwandt sind. Ideen?
MEHR INFO:
Ich habe tatsächlich eine Weile daran gearbeitet, die Frage zu vereinfachen. Wenn ich mehr Details hinzufüge, steigt die Komplexität um einiges. Aber was soll's... Ich glaube, ich kann es erklären.
Grundsätzlich bin ich schreiben ein GWT Web-Anwendungen RPC Servlet mit dem Befehl Muster, wie von Ray Ryan in seinem erklärt sprechen
Es gibt mehrere Implementierungen davon auf Google Code, aber viele von ihnen leiden unter diesem inhärenten Problem. Ich dachte, es war ein Fehler in der GWT-RPC-Code Bugreport WIE auch immer, als ich weiter implementierte, bemerkte ich ein ähnliches Problem rein auf der Client-Seite und im gehosteten Modus. (dh alle java, keine gwt javascript Wahnsinn).
Also abstrahierte ich die grundlegenden Ideen zu einer rohen Java-Befehlszeile Fall, und sah das gleiche Problem, wie oben beschrieben.
Wenn Sie den Ausführungen von Ray Ryan folgen, Foo
ist eine Aktion, SpecificFoo
ist eine bestimmte Aktion, die ich aufrufen möchte. SomeInterface
ist der clientseitige RPC-Dienst und SomeClass
ist die serverseitige RPC-Klasse. SomeOlderClass
ist eine Art rpc-Dienst, der sich mit Cacheing und dergleichen auskennt.
Offensichtlich, oder? Nun, wie ich schon sagte, denke ich, dass der ganze GWT RPC Unsinn nur das Wasser auf der Basis Frage verwirrt, weshalb ich versucht habe, es so gut ich konnte zu vereinfachen.