Копировать конструктор в Child, но не в Parent - PullRequest
8 голосов
/ 22 июня 2010

У меня есть два следующих класса:

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

public class SuperUser extends User {
}

Я хотел бы иметь конструктор в SuperUser, который принимает объект типа User и создает объект типа SuperUser.Например:

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

Если в объекте User отсутствует конструктор User (пользователь существующий пользователь), существует ли какой-либо автоматический способ инициализации объекта SuperUser со всеми полями из существующего пользовательского объекта?Я пытаюсь избежать 50 строк:

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

Если это невозможно, есть ли рефакторинг, такой как «Создать конструктор копирования?»

Спасибо!

Ответы [ 6 ]

9 голосов
/ 22 июня 2010

Взгляните на commons-beanutils 'BeanUtils.copyProperties(..):

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

В качестве альтернативы вы можете поместить это в конструктор копирования:

public SuperUser(User originalUser) {
   BeanUtils.copyProperties(this, originalUser);
}
4 голосов
/ 22 июня 2010

Несмотря на то, что вы можете использовать что-то вроде BeanUtils, чтобы делать то, что вы пытаетесь сделать, если вам нужно повысить статус пользователя до уровня SuperUser или понизить уровень уровня SuperUser до пользователя, вы используете правильную абстракцию.

Можетвы реорганизуете свой код так, чтобы у пользователя были разрешения или привилегии?В общем, когда я чувствую, что мне нужно изменить объект на другой объект в иерархии, я перестраиваю иерархию.

Например:

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

public interface Role {
}
public SuperUserRole implements Role {
}

Если вы не хотите вносить это изменение, тогда ответ Божо сработает.

1 голос
/ 22 июня 2010

Reflection & BeanUtils удобны, но медленны. Может быть стоит компромисс в вашем случае, но я бы их избегал. Кроме того, Object.clone () не даст вам того, что вы хотите .. потому что метод пользователя clone () (если реализован .. и, вероятно, нет) .. даст вам пользователя .. не SuperUser.

clone () используется редко. Конструктор копирования или фабричный метод являются разумными образцами.

Изменить: Забыл ответить на вопрос. Да, вручную реализовать конструктор копирования. Java == Много печатать.

0 голосов
/ 24 апреля 2015

Если вы хотите использовать BeanUtils на Android, но не повезло, попробуйте вместо этого android-java-air-bridge. https://code.google.com/p/android-java-air-bridge/

Просто скачайте android-java-air-bridge.jar.zip, извлеките .jar и импортируйте в свой проект, не нужно менять код.

Пример:

import javadz.beanutils.BeanUtils;

BeanUtils.copyProperties(superUser, originalUser);
0 голосов
/ 22 июня 2010

// ...another 50-60 fields.
Вместо String firstName и т. Д. У пользователя должны быть поля, такие как Name name, в котором есть первый, последний, заголовок и т. Д.

Вы можете сделать то же самое для своих адресов, контактдетали и т. д. Это значительно упростит конструктор копирования.

Кстати, поскольку SuperUser расширяет User, ваш конструктор будет

public SuperUser(User user){
    super(user); //the User constructor would do the copy
    //initialize other  fields...
}
0 голосов
/ 22 июня 2010

Пакет java.beans может справиться с этим:

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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...