Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy Constructor in Child but not Parent

Tags:

java

I have the following two classes:

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

public class SuperUser extends User {
}

I would like to have a constructor in SuperUser which takes an object of type User and creates an object of type SuperUser. For example:

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

If the User object lacks the constructor User(User existingUser), is there any automatic way to initialize the SuperUser object with all of the fields from the existing user object? I'm trying to avoid 50 lines of:

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

If this cannot be done, is there a refactoring like "Create Copy Constructor?"

Thanks!

like image 491
David Avatar asked Jun 22 '10 17:06

David


3 Answers

Take a look at commons-beanutils's BeanUtils.copyProperties(..):

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

Alternatively you can place this in the copy-constructor:

public SuperUser(User originalUser) {
   BeanUtils.copyProperties(this, originalUser);
}
like image 89
Bozho Avatar answered Oct 06 '22 00:10

Bozho


While you could use something like BeanUtils to do what you are trying to do, if you need to promote a User to SuperUser or demote a SuperUser to a User, are you using the right abstraction.

Could you refactor your code so that the User has permissions or privileges? In general when I feel I need to change an object to a different object in the hierarchy, I rearrange the hierarchy.

For example:

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

public interface Role {
}
public SuperUserRole implements Role {
}

If you don't want to make this change, then Bozho's answer would work.

like image 42
Aaron Avatar answered Oct 05 '22 22:10

Aaron


Reflection & BeanUtils are handy, but slow. May be worth the trade-off in your case, but I'd avoid them. Also, Object.clone() will not give you what you want.. because User's clone() method (if implemented.. and it's probably not).. will give you a User.. not a SuperUser.

clone() is rarely used. Copy constructor or a factory method are both reasonable patterns.

Edit: Forgot to answer the question. Yep, manually implement the copy constructor. Java == Lots of Typing.

like image 29
royal Avatar answered Oct 05 '22 22:10

royal