2011-01-15 5 views
6

ich die folgende Klassenstruktur:Java - Zurück richtigen Typ von Generic Methode

public class Team { 
    ... 
} 

public class Event { 

} 

public abstract class Fixture<T extends Team> implements Event { 
    ... 
} 

public abstract class Forecast<Event> { 

} 

public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{ 

} 

Ich versuche, Sportveranstaltungen aller Art zu modellieren (dh eine ‚Fixture‘ ist für ein bestimmtes Spiel zwischen zwei Teilnehmern spielen gegeneinander, während eine andere Art von "Ereignis" viele Teilnehmer haben kann, zusammen mit Vorhersagen für das Ergebnis bestimmter "Ereignisse". Ich habe eine generische Methode:

public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) { 

}

Ich möchte eine MyPrediction Instanz zurückkehren können, die die Gattung des fixture Argument hat, aber ich kann es nicht zu tun scheinen. Zum Beispiel, wenn ich so etwas wie die folgenden tun, dann erhalte ich einen Übersetzungsfehler:

SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>(); 
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch); 

Ich bin bereit, meine Klassenstruktur zu ändern, um diese Funktion zu übernehmen. Wie kann ich das tun?

+1

"Wenn ich etwas wie das Folgende mache" ... dann (auf welches Problem stoßen Sie)? –

+0

es sieht aus wie Event muss eine Schnittstelle sein –

Antwort

1

ändern die Signatur von getMyPrediction zu

public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) 

Dies teilt den Compiler, dass die Gerätetypen im Argumente einer Das Ergebnis ist das gleiche und erlaubt die Typprüfung.

Hier ist ein vollständiges Beispiel mit einigen anderen kleinen Änderungen, um es kompilieren zu lassen. Es führt die Klasse Predictor die getMyPrediction Verfahren und eine doit Methode zu halten Probe Verwendung zeigen:

public interface Team { 
} 

public interface Event { 
} 

public abstract class Fixture<T extends Team> implements Event { 
} 

public abstract class Forecast<T> { 
} 

public class MyPrediction<T extends Fixture<? extends Team>> extends 
     Forecast<Fixture<? extends Team>> { 
} 

public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> { 
} 

public class SoccerTeam implements Team { 
} 

public class EnglishSoccerTeam extends SoccerTeam { 
} 

public class Predictor { 

    public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) { 
     return new MyPrediction<T>(); 
    } 

    public void doit() { 
     SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>(); 
     MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch); 
    } 
} 

Wie an anderer Stelle erwähnt, müssen Sie möglicherweise ein oder mehr Fabrikobjekte einzuführen sinnvolle Arbeit in der MyPrediction Umsetzung durchzuführen.

0

Java-Typ-System ist nicht stark genug, um direkt zu tun, was Sie vorschlagen, aufgrund Typs Löschung (die allgemeinen Parameter zur Laufzeit nicht zur Verfügung.

Die übliche Lösung ist eine separate EventFactory Klasse zu erstellen, wo Sie Pass in dann auf jedes Verfahren, das eine spezifische Ereignis-Subtyp-Instanz erstellen muss.