2010-06-22 11 views
8

Ho le seguenti due classi:costruttore di copia in Child ma non Parent

public class User { 
    public Integer userId; 
    // ...another 50-60 fields 
} 

public class SuperUser extends User { 
} 

mi piacerebbe avere un costruttore in SuperUser che prende un oggetto di tipo utente e crea un oggetto di tipo SuperUser. Per esempio:

public SuperUser(User theUser) { 
    // not legal -> but I am looking for a one-liner to initialize this with values from theUser 
    this = theUser; 
} 

Se l'oggetto utente manca il costruttore utente (User existingUser), non v'è alcun modo automatico per inizializzare l'oggetto SuperUser con tutti i campi dalla oggetto utente esistente? Sto cercando di evitare 50 linee di:

public SuperUser(User theUser) { 
    this.firstName = theUser.getFirstName(); 
    this.lastName = theUser.getLastName(); 
    // and so on.... 
} 

Se ciò non può essere fatto, c'è un refactoring come "Crea copia Constructor?"

Grazie!

risposta

9

Date un'occhiata a commons-beanutils s' BeanUtils.copyProperties(..):

SuperUser superUser = new SuperUser(); 
BeanUtils.copyProperties(superUser, originalUser); 

In alternativa è possibile inserire questo nel costruttore di copia:

public SuperUser(User originalUser) { 
    BeanUtils.copyProperties(this, originalUser); 
} 
1

riflessione & BeanUtils sono a portata di mano, ma lento. Potrebbe valere il trade-off nel tuo caso, ma li eviterei. Inoltre, Object.clone() non ti darà quello che vuoi ... perché il metodo clone() dell'utente (se implementato .. e probabilmente non lo è) ... ti darà un utente .. non un SuperUser.

clone() è usato raramente. Copia costruttore o un metodo di fabbrica sono entrambi modelli ragionevoli.

Modifica: Hai dimenticato di rispondere alla domanda. Sì, implementa manualmente il costruttore di copie. Java == Un sacco di digitazione.

+1

Non credo che stai rispondendo alla domanda;) – Bozho

+0

Ma, se non ricordo male, non ci sono veri costruttori di copia dedicati in Java, così come può li usare? – AndrejaKo

+0

Li implementate manualmente. – royal

0

Il pacchetto java.beans in grado di gestire questa roba:

User u = ...; 
SuperUser su = ...; 
BeanInfo bi = Introspector.getBeanInfo(User.class); 
for (PropertyDescriptor pd : bi.getPropertyDescriptors()) { 
    Method getter = bi.getReadMethod(), setter = bi.getWriteMethod(); 
    if (getter == null || setter == null) continue; 
    setter.invoke(su, getter.invoke(u)); 
} 
0

// ...another 50-60 fields.
Invece di String firstName ecc, l'utente dovrebbe avere campi come Name name, che ha in primo luogo, l'ultima, titolo, ecc

Si potrebbe fare lo stesso vale per gli indirizzi, i dettagli di contatto, ecc. Ciò renderebbe un costruttore di copie piuttosto semplice.

BTW, dal momento che SuperUser estende l'utente, il vostro costruttore sarebbe

public SuperUser(User user){ 
    super(user); //the User constructor would do the copy 
    //initialize other fields... 
} 
+0

che presuppone di avere un costruttore: utente pubblico (Utente esistente) Non ho un tale costruttore ...... – David

+0

In realtà, si presume che sia possibile creare un super costruttore 'protetto' (' Utente protetto (Utente esistente) '). – Stephen

4

Mentre si potrebbe usare qualcosa come BeanUtils di fare ciò che si sta cercando di fare, se è necessario promuovere un utente a SuperUser o abbassare di livello un SuperUser per un utente, stai usando l'astrazione giusta.

Si può effettuare il refactoring del codice in modo che l'utente disponga di autorizzazioni o privilegi? In generale, quando sento che ho bisogno di cambiare un oggetto in un oggetto diverso nella gerarchia, riorganizzo la gerarchia.

Ad esempio:

public class User { 
    public Integer userId; 
    // ...another 50-60 fields 
    public Role role; 
} 

public interface Role { 
} 
public SuperUserRole implements Role { 
} 

Se non si vuole fare questo cambiamento, allora la risposta di Bozho avrebbe funzionato.

0

Se si desidera utilizzare BeanUtils su Android ma senza fortuna, provare Android-java-air-bridge. https://code.google.com/p/android-java-air-bridge/

Basta scaricare android-java-air-bridge.jar.zip, estrarre il file .jar e importarlo nel progetto, non è necessario modificare alcun codice.

Esempio:

import javadz.beanutils.BeanUtils; 

BeanUtils.copyProperties(superUser, originalUser); 
Problemi correlati