2013-04-04 14 views
10
public class Base { 
    //long list of attributes 
    // no Constructor using fields 
    // no init methode 
    // i cannot change this class 
} 

ora ho esteso la classe di base come:java, inizializzare SubClass da SuperClass

public class subClass extends Base{ 
    private boolean selected; 

    ... 
    getter und setter 
    ... 
} 

divento un elenco di oggetti Base List<Base>

ma ho bisogno la stessa lista ma come List<SubClass> è c'è un modo per inizializzare la Sottoclasse dalla Base Class?

esempio:

for(Base b: list){ 
    SubClass sub = (SubClass)b; // Thats wrong i know 
    if(...){ 
     sub.setSelected(true); 
    } 
    newList.add(sub); 
} 

cerco di evitare l'init manuale di ciascun attributo della Base Class alla sottoclasse

aggiorno mia interrogazione, come richiesto nei commenti: il disegno qui sopra è solo un esempio. il mio QUESTIN ESATTAMENTE È:

perché la conversione di BaseClass in SubClass (sione Subclass extends BaseClass) non è possibile? perché Java dos non mi permetterà di fare il seguente:

esempio:

Class Base{ 
    private String name; 
..... 
} 
Class SubClass extends Base{ 
    private String title; 
} 

poi

Base b = DBController.getById(...); 
SubClass sub = (SubClass)b; 

dopo che l'oggetto sub dovrebbe avere il nome attributo dall'oggetto b e la title L'attributo è nullo

perché non è questo il caso in java?

dispiace per il mio cattivo inglese, grazie

+2

Inizializza sottoclasse dalla superclasse - perché? Questo sembra mal concepito nel migliore dei casi e pericoloso nel peggiore dei casi. –

+0

Dove è definito il campo 'Elenco '? Nella classe 'Base' stessa? Hai il controllo su dove è stato dichiarato e su come è stato inizializzato? – Perception

+1

Consiglio vivamente di esaminare "preferisci la Composizione sull'ereditarietà" - google it. Troverete alcune discussioni interessanti sull'argomento. Dico solo perché sembra che tu stia tentando disperatamente di abusare del privilegio. –

risposta

7

Se si dispone di un List<Base>, allora non si può convertirlo in un List<SubClass>. Ciò è principalmente dovuto al fatto che l'elenco non può contenere istanze di SubClass. Il meglio che puoi fare è:

List<SubClass> newList = new List<SubClass>(); 
for(Base b: list){ 
    if (b instanceof SubClass) { 
     SubClass sub = (SubClass)b; 
     . . . 
     newList.add(sub); 
    } 
} 

In generale, tuttavia, quando vi trovate a fare questo genere di cose, c'è qualcosa di sbagliato con il vostro disegno. È possibile evitare la sottoclasse Base e utilizzare composition instead.

EDIT sulla base di osservazioni, suona come si vuole costruire una lista di SubClass istanze tramite un elenco di Base casi come un inizio. Un approccio consiste nel definire un costruttore per SubClass che accetta un argomento come Base.

public class SubClass extends Base{ 
    private boolean selected; 

    public SubClass() { 
     // default constructor 
    } 

    public SubClass(Base original) { 
     // copy constructor -- initialize some fields from 
     // values in original, others with default values 
    } 
    ... 
    getter und setter 
    ... 
} 

Poi si può costruire la vostra nuova lista con:

List<SubClass> newList = new List<SubClass>(); 
for(Base b: list){ 
    SubClass sub = new SubClass(b); 
    . . . 
    newList.add(sub); 
} 
+0

grazie per la risposta. la lista ha solo il tipo di oggetto Base, quindi non ci sono esempi di sottoclassi nella lista. ma perché il casting della classe è sbagliato? gli attributi nella sottoclass potrebbero essere nulli dopo il casting, i posso impostarli manualmente come nel mio esempio sopra. Cosa ci pensi? –

+0

Voglio dire, dopo aver lanciato SubClass dovrebbero avere tutti gli attributi della Base Class e gli altri Attributi in SubClass sarebbero nulli –

+0

@ Rami.Q - Ok, i tuoi commenti mi hanno chiarito qualcosa su quello che vuoi. Ho rivisto la mia risposta per affrontare questo. –

2

Si sembrano avere una classe con un sacco di attributi e non c'è modo semplice di tutti loro impostazione. Ora hai eseguito un problema in cui hai bisogno di una classe con un attributo aggiuntivo, ma devi affrontare quel casino di una classe base.

suggerisco, invece di creare una sottoclasse e la colata, si crea una classe wrapper per il brutto:

public class BigDumbClass { 
    // A lot of attributes 
    // No Constructor 
    // No init method 
} 

public class Wrapper { 
    private BigDumbClass base; 
    private boolean selected; 

    public Wrapper(BigDumbClass base) { 
     this.base = base; 
     this.selected = false; 
    } 

    //getters and setters 
} 

Ora, quando si deve creare quella nuova lista si può avvolgere tutto nella vecchia lista

List<BigDumbClass> oldList = someData(); 
List<Wrapper> wraps = aNewList(); 
for (BigDumbClass bigDumb : oldList) { 
    Wrapper wrap = new Wrapper(bigDumb); 
    if (someCondition()) { 
     wrap.setSelected(true); 
    } 
    wraps.add(wrap); 
} 

Idealmente, sarebbe BigDumbClass implementare un'interfaccia che involucro potrebbe anche implementare, consentendo l'involucro di differire tutte le chiamate verso l'istanza è avvolto.

public class BigDumbClass implements SharedInterface { 
    // All the stuff outlined above 
} 

public class Wrapper implements SharedInterface { 
    // All the stuff outlined above 

    // Methods defined in SharedInterface 
    public void doSomething() { 
     base.doSomething(); 
    } 
} 

In caso contrario, è possibile fornire un getter all'istanza e accedervi direttamente.

BigDumbClass base = wrapper.getBase(); 
base.doSomething(); 
+0

Solo perché hai un riferimento per una super classe non significa che stai puntando a una super classe. 'Base baseRef' potrebbe puntare a una Sottoclassula1, quindi 'SubClass2 subRef = (Sottoclassico2) baseRef' non è un cast valido. –

2

C'è una via: based manipulation Vari Java Beans spec.

Ad esempio:

Commons BeanUtils

for(Base base: list){ 
    SubClass sub = new SubClass(); 
    PropertyUtilsBean.copyProperties(sub, base); 
    if(...){ 
     sub.setSelected(true); 
    } 
    newList.add(sub); 
} 

Questa Funziona sulla base di ricevere/setter con lo stesso nome. Non copia i campi interni.

Se è necessario copiare i campi interni, in realtà non è così difficile da implementare utilizzando javax.lang.reflect.

Problemi correlati