2012-10-24 11 views
20

Ho una classe astratta Vehicle con 2 sottoclassi implementate RedVehicle e YellowVehicle.Passare in una sottoclasse a un metodo ma avere la super classe come parametro?

In un'altra classe ho un List<Vehicle> contenente istanze di entrambe le sottoclassi. Voglio essere in grado di passare a un metodo un tipo di classe e quindi utilizzare quel tipo per decidere quale serie di oggetti voglio fare qualcosa nello List.

Dal Class è generico dovrei parametrizzare con qualcosa, ma mettendo il parametro come la classe padre Vehicle ferma il codice chiamante opera dal exampleMethod è ora in attesa di un tipo di veicolo, non è una sottoclasse di RedVehicle o YellowVehicle.

Penso che ci dovrebbe essere un modo pulito per farlo, quindi quale sarebbe il modo corretto di implementare la funzionalità?

n.b. Non devo necessariamente passare nel tipo Class, se ci sono suggerimenti migliori sarei felice di provare quelli.

Prefisso telefonico internazionale:

service.exampleMethod(RedVehicle.class); 
service.exampleMethod(YellowVehicle.class); 

Campi/Metodo:

//List of vehicles 
//Vehicle has 2 subclasses, RedVehicle and YellowVehicle 
private List<Vehicle> vehicles; 

//Having <Vehicle> as the Class parameter stops the calling code working 
public void exampleMethod(Class<Vehicle> type) 
{ 
    for(Vehicle v : vehicles) 
    { 
     if(v.getClass().equals(type)) 
     { 
      //do something 
     } 
    } 
} 

risposta

41

fare questo, invece:

public <T extends Vehicle> void exampleMethod(Class<T> type) 
+0

Sapevo che sarebbe stato qualcosa di semplice. C'è un nome speciale per avere il tipo generico prima del tipo restituito/un link ad una fonte generale sarebbe bello. Ci proverò e domani e accetto se funziona grazie. – Peanut

+1

dai un'occhiata alla presentazione dei generici di oracle o alle domande frequenti sui generici java di angelika langer. +1 per la soluzione diretta di mprivat. – DaveFar

+0

@DaveBall Grazie per il suggerimento di angelika langer, sono consapevole del concetto di generici e li ho usati ma non li ho mai guardati in profondità, sembra una discussione approfondita su di essi. Il link per chiunque sia interessato: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html – Peanut

4

Perché non utilizzare il visitor pattern?

In questo modo si

  • non hanno bisogno di tipo token
  • lasciare che la spedizione dinamica gestire il caso distinzione (invece di if(v.getClass().equals(type)))
  • sono più flessibili (segue OCP)

In dettaglio:

la classe astratta Vehicle ottiene un metodo accept(Visitor v), con le sottoclassi che lo implementano chiamando il metodo appropriato su v.

public interface Visitor { 
    visitRedVehicle(RedVehicle red); 
    visitYellowVehicle(YellowVehicle yellow); 
} 

Utilizzando un visitatore:

public class Example { 

    public void useYellowOnly() { 
    exampleMethod(new Visitor() { 
     visitRedVehicle(RedVehicle red) {}; 
     visitYellowVehicle(YellowVehicle yellow) { 
      //...action 
     }); 
    } 
    public void exampleMethod(Visitor visitor){ 
     for(Vehicle v : vehicles) { 
      v.accept(visitor); 
     } 
    } 
} 
Problemi correlati