2010-06-22 30 views
8

Tôi đã sau hai lớp:Sao chép Constructor trong Child nhưng không Chánh

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

public class SuperUser extends User { 
} 

Tôi muốn có một constructor trong superuser mà phải mất một đối tượng của loại tài khoản và tạo một đối tượng kiểu superuser. Ví dụ:

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

Nếu đối tượng người dùng thiếu các nhà xây dựng tài khoản (User existingUser), có cách nào tự động để khởi tạo đối tượng superuser với tất cả các lĩnh vực từ đối tượng người dùng hiện có? Tôi đang cố gắng tránh 50 dòng:

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

Nếu không thể thực hiện được, có tái cấu trúc như "Tạo bản sao chép không?"

Cảm ơn!

Trả lời

9

Hãy xem commons-beanutils 's BeanUtils.copyProperties(..):

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

Hoặc bạn có thể đặt này trong bản sao-constructor:

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

Reflection & BeanUtils là tiện dụng, nhưng chậm. Có thể đáng được cân bằng trong trường hợp của bạn, nhưng tôi sẽ tránh chúng. Ngoài ra, Object.clone() sẽ không cung cấp cho bạn những gì bạn muốn .. bởi vì phương thức clone() của người dùng (nếu được triển khai .. và có thể là không) .. sẽ cung cấp cho bạn một User .. không phải là SuperUser.

sao chép() hiếm khi được sử dụng. Sao chép hàm tạo hoặc phương thức nhà máy đều là các mẫu hợp lý.

Chỉnh sửa: Quên trả lời câu hỏi. Đúng, thực hiện thủ công hàm tạo bản sao. Java == Rất nhiều đánh máy.

+1

Tôi không nghĩ rằng bạn đang trả lời câu hỏi;) – Bozho

+0

Nhưng, nếu tôi nhớ không lầm, không có thực dành riêng cho nhà xây dựng bản sao trong Java, vậy làm thế nào bạn có thể sử dụng chúng? – AndrejaKo

+0

Bạn thực hiện thủ công chúng. – royal

0

Gói java.beans có thể xử lý công cụ này:

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.
Thay vì String firstName vv, Người sử dụng cần có các trường như Name name, trong đó có đầu tiên, cuối cùng, tiêu đề, vv

Bạn có thể làm tương tự cho địa chỉ của bạn, chi tiết liên lạc vv Điều này sẽ làm cho một nhà xây dựng bản sao khá dễ dàng hơn.

BTW, kể từ superuser mở rộng dùng, nhà xây dựng của bạn sẽ là

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

giả sử tôi có một hàm tạo: Người dùng công khai (Người dùng hiện tại) Tôi không có một nhà xây dựng như vậy ...... – David

+0

Thực ra, nó giả định rằng bạn có thể tạo một trình tạo cấu trúc 'được bảo vệ' (' Người dùng được bảo vệ (Người dùng được bảo vệ) hiện tại) '). – Stephen

4

Trong khi bạn có thể sử dụng một cái gì đó giống như BeanUtils để làm những gì bạn đang cố gắng để làm, nếu bạn cần để thúc đẩy một tài khoản để superuser hoặc demote một SuperUser cho một người dùng, bạn đang sử dụng trừu tượng đúng.

Bạn có thể cấu trúc lại mã của mình để Người dùng có quyền hoặc đặc quyền không? Nói chung khi tôi cảm thấy tôi cần phải thay đổi một đối tượng cho một đối tượng khác trong cấu trúc phân cấp, tôi sắp xếp lại cấu trúc phân cấp.

Ví dụ:

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

public interface Role { 
} 
public SuperUserRole implements Role { 
} 

Nếu bạn không muốn thực hiện thay đổi này, sau đó câu trả lời Bozho của sẽ làm việc.

0

Nếu bạn muốn sử dụng BeanUtils trên Android nhưng không may mắn, hãy thử android-java-air-bridge để thay thế. https://code.google.com/p/android-java-air-bridge/

Chỉ cần tải xuống android-java-air-bridge.jar.zip, trích xuất .jar và nhập vào dự án của bạn, không cần thay đổi bất kỳ mã nào.

Ví dụ:

import javadz.beanutils.BeanUtils; 

BeanUtils.copyProperties(superUser, originalUser); 
Các vấn đề liên quan