2011-01-15 9 views
6

ho la seguente struttura di classe:Java - Tornare tipo corretto dal metodo generico

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>>{ 

} 

Sto cercando di modellare gli eventi sportivi di ogni genere (cioè un 'Fixture' è per un particolare gioco tra due partecipanti giocano l'uno contro l'altro, mentre un altro tipo di "Evento" può avere molti partecipanti), insieme alle previsioni per l'esito di particolari "Eventi". Ho un metodo generico:

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

}

voglio essere in grado di restituire un'istanza MyPrediction che ha il tipo generico dell'argomento fixture, ma io non riesco a farlo. Ad esempio, se faccio qualcosa di simile a quanto segue, quindi ottengo un errore di compilazione:

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

io sono disposto a cambiare la mia struttura di classe per incorporare questa funzionalità. Come posso farlo?

+1

"Se faccio qualcosa come il seguente" ... allora (quale problema incontrate)? –

+0

sembra che Event debba essere un'interfaccia –

risposta

1

Modificare la firma del getMyPrediction per

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

Questo dice al compilatore che gli elementi di fissaggio in discussione un I risultati sono gli stessi, consentendo il passaggio del controllo dei tipi.

Ecco un esempio completo, con alcune altre modifiche minori per farlo compilare. Si introduce la classe Predictor di tenere il metodo getMyPrediction e un metodo doit per dimostrare l'uso del campione:

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); 
    } 
} 

Come notato altrove, potrebbe essere necessario introdurre uno o più oggetti di fabbrica per svolgere un lavoro significativo nel MyPrediction attuazione.

0

sistema di tipo Java non è abbastanza potente per fare direttamente ciò che si propone, a causa della cancellazione di tipo (i parametri generici non sono disponibili in fase di esecuzione.

La soluzione più comune è quella di creare una classe EventFactory separato, che è possibile poi passare a un modo che ha bisogno di creare una specifica istanza evento sottotipo.