2016-04-11 5 views
0

Ich habe eine Reihe von Klassen, die eine Basisklasse erweitern. Die Basisklasse wurde ein Verfahren sollen wir sagen:java Generics - Wie Kind overloaded Methode zu wissen, die Kind-Klasse-Typ und die Oberklasse

doStuff1(int variable){ do something;} 

Jede dieser Klassen haben:

doStuff1(String string) {convert string to number and call super.doStuff1(intResult)}; 

In einer anderen Klasse, Methode Ich habe so etwas wie:

public void bla(Class<?> childClass, SuperClass childClassInDisguise) { 
    (childClass.cast(childClassInDisguise)).doStuff1(myString); 
} 

kann ich nicht kompilieren Sie das wegen: Die Methode doStuff1 (myString) ist nicht definiert für den Typ capture # 17-of?

Was mache ich hier falsch? Ist das überhaupt möglich?

Danke.

+0

(vielleicht unabhängig) Wenn Sie es in jeder Kindklasse implementieren, warum machen Sie es nicht abstrakt? Auch: Ich habe diese Art von Besetzung nie gesehen (nicht zu sagen, dass es nicht funktioniert); warum nicht das klassische '((SuperClass) childInDisguise) .doStuff1 (myString);'? – dquijada

+0

Ist 'doStuff1 (String)' eine Methode der Basisklasse? –

+0

'' '(childClass.cast (childClassInDisguise))' '' gibt ein Objekt zurück, nicht SuperClass. Ändern zu '' 'void blah (Klasse ' '' – Joseph

Antwort

0

Der Compiler weiß nicht, welche Klasse stellt dies zu,

Class<?> 

und der einzige Hinweis, es in Bezug auf das Objekt weiß ist, dass es eine übergeordnete Klasse hat, die erst doStuff1 (int)

Wenn Sie doStuff1 (String) wirklich aufrufen möchten, erstellen Sie eine andere abstrakte Unterklasse, die diese Methode enthält, und markieren Sie diese Methode als abstrakt. Die vorhandenen Unterklassen sollten diese neue Unterklasse erweitern.

public abstract class NewSubclass extends Superclass { 
    public void abstract doStuff1(String); 
} 

Dann in Ihrer Methode, einen generischen Parameter hinzuzufügen wie

public <T extends NewSubclass>void bla(Class<T> childClass, SuperClass childClassInDisguise) { 
     (childClass.cast(childClassInDisguise)).doStuff1(myString); 
    } 

Auf diese Weise der Compiler die Vererbungshierarchie des Objekts weiß, welche Unterklassen des NewSubclass sind, die die abstrakte Methode enthält. wenn die Bedingung in anderen bekannten Subklassen

EDIT

Wenn Sie nur bla Methode bearbeiten können, versuchen Sie dies,

public void bla(Class<?> childClass, SuperClass childClassInDisguise) { 
     if(childClass.equals(ChildClass1.class) { 
     (ChildClass1(childClassInDisguise)).doStuff1(myString); 
    } else ... { 
    } 
} 

das gleiche tun. Ich weiß, dass es hardcodiert ist, aber dies ist der einzige Weg, wenn Sie die generische + abstrakte Superklasse nicht verwenden können, indem Sie die beteiligten Klassen modifizieren. Aber ich bevorzuge immer noch meinen ersten Vorschlag, da es weniger Code und Dynamik hat, wie wenn du eine andere Unterklasse hinzufügst, du musst die bla-Methode nicht erneut ändern (die Kraft von POLYMORPHISM), im Gegensatz zum zweiten Vorschlag. Dies ist eher ein Problem der Designrekonstruktion.

+0

gibt es einen anderen Weg, weil es scheint, dass ich die vorgeschlagene Modifikation nicht tun kann. – John11

+0

Ja, Sie können versuchen, ein Strategie-Pattern zu verwenden, in dem instanceof auf childClass verwendet wird, wenn es zu einer der Unterklassen mit doStuff1 passt, aber dies ist eine Art fest codierter Code. Aber welchen Code können Sie direkt ändern? – vine

+0

Ich kann nur den Code ändern, der die Methode bla enthält. – John11

Verwandte Themen