2010-06-22 5 views
8

j'ai les deux catégories suivantes:Copie en Constructor enfant mais non Parent

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

public class SuperUser extends User { 
} 

Je voudrais avoir un constructeur dans SuperUser qui prend un objet de type utilisateur et crée un objet de type super-utilisateur. Par exemple:

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

Si l'objet utilisateur n'a pas le constructeur utilisateur (User existingUser), est-il un moyen automatique pour initialiser l'objet SuperUser avec tous les champs de l'objet utilisateur existant? J'essaie d'éviter 50 lignes de:

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

Si cela ne peut se faire, est-il un refactoring comme « Créer une copie Constructor? »

Merci!

Répondre

9

Jetez un oeil à commons-beanutils « s BeanUtils.copyProperties(..):

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

Sinon, vous pouvez placer dans le constructeur de copie:

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

Réflexion & BeanUtils sont à portée de main, mais lent. Cela vaut peut-être le compromis dans votre cas, mais je les éviterais. En outre, Object.clone() ne vous donnera pas ce que vous voulez .. parce que la méthode clone() de l'utilisateur (si elle est implémentée .. et ce n'est probablement pas) .. vous donnera un utilisateur .. pas un SuperUser.

clone() est rarement utilisé. Le constructeur de copie ou une méthode d'usine sont deux modèles raisonnables.

Editer: J'ai oublié de répondre à la question. Oui, implémentez manuellement le constructeur de copie. Java == Beaucoup de dactylographie.

+1

Je ne pense pas que vous répondez à la question;) – Bozho

+0

Mais, si je me souviens bien, il n'y a pas de vrais constructeurs de copie dédiés à Java, alors comment pouvez-vous les utiliser? – AndrejaKo

+0

Vous les implémentez manuellement. – royal

0

Le paquet java.beans peut gérer ce genre de choses:

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.
Au lieu de String firstName etc, l'utilisateur doit avoir des champs comme Name name, qui a d'abord, le dernier, le titre, etc.

Vous pourriez faire la même chose pour vos adresses, vos coordonnées, etc. Cela rendrait un constructeur de copie plutôt facile.

BTW, depuis SuperUser étend l'utilisateur, votre constructeur serait

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

qui suppose que j'ai un constructeur: public User (utilisateur existant) Je n'ai pas un tel constructeur ...... – David

+0

En fait, il suppose que vous pouvez créer un super constructeur 'protected' (' Utilisateur protégé (User existant) '). – Stephen

4

Alors que vous pouvez utiliser quelque chose comme BeanUtils faire ce que vous essayez de faire, si vous avez besoin de promouvoir un utilisateur à SuperUser ou rétrograder un SuperUser à un utilisateur, utilisez-vous la bonne abstraction.

Pourriez-vous refactoriser votre code afin que l'utilisateur dispose d'autorisations ou de privilèges? En général, lorsque je sens que j'ai besoin de changer un objet en un objet différent dans la hiérarchie, je réorganise la hiérarchie.

Par exemple:

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

public interface Role { 
} 
public SuperUserRole implements Role { 
} 

Si vous ne voulez pas faire ce changement, alors la réponse de Bozho fonctionnerait.

0

Si vous voulez utiliser BeanUtils sur Android mais pas de chance, essayez plutôt android-java-air-bridge. Il suffit de télécharger le fichier android-java-air-bridge.jar.zip, d'extraire le fichier .jar et de l'importer dans votre projet, pas besoin de changer de code.

Exemple:

import javadz.beanutils.BeanUtils; 

BeanUtils.copyProperties(superUser, originalUser);