2013-04-04 41 views
10
public class Base { 
    //long list of attributes 
    // no Constructor using fields 
    // no init methode 
    // i cannot change this class 
} 

bây giờ tôi mở rộng Base Class như:java, khởi tạo lớp con từ SuperClass

public class subClass extends Base{ 
    private boolean selected; 

    ... 
    getter und setter 
    ... 
} 

tôi trở thành một danh sách các đối tượng cơ sở List<Base>

nhưng tôi cần phải cùng một danh sách nhưng như List<SubClass> là có cách nào để khởi tạo lớp con từ lớp cơ sở?

dụ:

for(Base b: list){ 
    SubClass sub = (SubClass)b; // Thats wrong i know 
    if(...){ 
     sub.setSelected(true); 
    } 
    newList.add(sub); 
} 

tôi cố gắng để tránh những init thủ công của mỗi thuộc tính của cơ sở Class đến lớp con

tôi cập nhật Câu hỏi của tôi như yêu cầu trong trường Nhận xét: thiết kế ở trên chỉ là một ví dụ. QUESTIN CHÍNH XÁC CỦA TÔI LÀ:

tại sao chuyển đổi BaseClass thành SubClass (sence Subclass extends BaseClass) là không thể? tại sao Java Dosn't cho phép tôi làm như sau:

dụ:

Class Base{ 
    private String name; 
..... 
} 
Class SubClass extends Base{ 
    private String title; 
} 

sau đó

Base b = DBController.getById(...); 
SubClass sub = (SubClass)b; 

sau đó các đối tượng sub nên có tên thuộc tính từ các đối tượng btitle Thuộc tính là null

tại sao đây không phải là trường hợp trong java?

xin lỗi vì tiếng anh xấu, nhờ tôi

+2

Khởi tạo lớp con từ lớp cha - tại sao? Điều này nghe có vẻ không tốt và nguy hiểm nhất. –

+0

Trường 'Liệt kê ' được xác định ở đâu? Trong chính lớp 'Base'? Bạn có quyền kiểm soát nơi nó được khai báo và cách khởi tạo của nó không? – Perception

+1

Tôi đánh giá cao đề nghị bạn nhìn vào "thích Thành phần hơn thừa kế" - google nó. Bạn sẽ tìm thấy một số cuộc thảo luận thú vị về vấn đề này. Tôi chỉ nói điều này bởi vì có vẻ như bạn đang cố gắng tuyệt vọng để lạm dụng đặc quyền đó. –

Trả lời

7

Nếu bạn có một List<Base>, thì bạn không thể chuyển nó sang một List<SubClass>. Điều này chủ yếu là do danh sách có thể không chứa các phiên bản SubClass. Điều tốt nhất bạn có thể làm là:

List<SubClass> newList = new List<SubClass>(); 
for(Base b: list){ 
    if (b instanceof SubClass) { 
     SubClass sub = (SubClass)b; 
     . . . 
     newList.add(sub); 
    } 
} 

Nói chung, tuy nhiên, khi bạn thấy mình làm điều này, có điều gì đó sai với thiết kế của bạn. Bạn có thể muốn tránh phân lớp Base và sử dụng composition instead.

EDIT Dựa trên nhận xét của bạn, có vẻ như bạn muốn tạo danh sách SubClass trường hợp sử dụng danh sách các trường hợp Base làm khởi đầu. Một cách tiếp cận là định nghĩa một hàm tạo cho SubClass lấy một đối số Base.

public class SubClass extends Base{ 
    private boolean selected; 

    public SubClass() { 
     // default constructor 
    } 

    public SubClass(Base original) { 
     // copy constructor -- initialize some fields from 
     // values in original, others with default values 
    } 
    ... 
    getter und setter 
    ... 
} 

Sau đó, bạn có thể xây dựng danh sách mới của bạn với:

List<SubClass> newList = new List<SubClass>(); 
for(Base b: list){ 
    SubClass sub = new SubClass(b); 
    . . . 
    newList.add(sub); 
} 
+0

cảm ơn câu trả lời. Danh sách chỉ có các kiểu đối tượng của cơ sở, vì vậy đây không phải là trường hợp của lớp con trong danh sách. nhưng tại sao đúc lớp là sai? thuộc tính trong SubClass có thể là null sau khi đúc, tôi có thể thiết lập nó theo cách thủ công như trong ví dụ trên. bạn làm gì thế? –

+0

tôi có nghĩa là, sau khi đúc SubClass nên có tất cả các thuộc tính của lớp cơ sở và phần còn lại thuộc tính trong SubClass sẽ là null –

+0

@ Rami.Q - Được rồi, ý kiến ​​của bạn làm rõ cho tôi một cái gì đó về những gì bạn muốn. Tôi đã sửa đổi câu trả lời của mình để giải quyết vấn đề này. –

2

Dường như bạn có một lớp học với rất nhiều các thuộc tính và không có cách nào dễ dàng thiết lập tất cả chúng. Bây giờ bạn đã chạy vào một vấn đề mà bạn cần một lớp với một thuộc tính bổ sung nhưng bạn phải đối phó với mớ hỗn độn của một lớp cơ sở.

Tôi đề nghị rằng, thay vì tạo một lớp con và đúc, bạn tạo một lớp bao bọc xung quanh xấu xí một:

public class BigDumbClass { 
    // A lot of attributes 
    // No Constructor 
    // No init method 
} 

public class Wrapper { 
    private BigDumbClass base; 
    private boolean selected; 

    public Wrapper(BigDumbClass base) { 
     this.base = base; 
     this.selected = false; 
    } 

    //getters and setters 
} 

Bây giờ khi bạn phải tạo rằng danh sách mới, bạn có thể bọc mọi thứ trong danh sách cũ

List<BigDumbClass> oldList = someData(); 
List<Wrapper> wraps = aNewList(); 
for (BigDumbClass bigDumb : oldList) { 
    Wrapper wrap = new Wrapper(bigDumb); 
    if (someCondition()) { 
     wrap.setSelected(true); 
    } 
    wraps.add(wrap); 
} 

Lý tưởng nhất, BigDumbClass sẽ triển khai giao diện mà Trình bao bọc cũng có thể thực hiện, cho phép trình bao bọc trì hoãn tất cả các cuộc gọi đến trường hợp đã gói.

public class BigDumbClass implements SharedInterface { 
    // All the stuff outlined above 
} 

public class Wrapper implements SharedInterface { 
    // All the stuff outlined above 

    // Methods defined in SharedInterface 
    public void doSomething() { 
     base.doSomething(); 
    } 
} 

Nếu không, bạn có thể cung cấp thông tin trực tiếp cho cá thể và truy cập trực tiếp.

BigDumbClass base = wrapper.getBase(); 
base.doSomething(); 
+0

Chỉ vì bạn có một tham chiếu cho một lớp học siêu không có nghĩa là bạn đang trỏ đến một lớp học siêu hạng. 'Base baseRef' có thể trỏ đến SubClass1, vì vậy 'SubClass2 subRef = (SubClass2) baseRef' không phải là một phép tính hợp lệ. –

2

Có một cách: Nhiều thao tác dựa trên thông số kỹ thuật Java.

Ví dụ:

Commons BeanUtils

for(Base base: list){ 
    SubClass sub = new SubClass(); 
    PropertyUtilsBean.copyProperties(sub, base); 
    if(...){ 
     sub.setSelected(true); 
    } 
    newList.add(sub); 
} 

này làm việc dựa trên nhận/setters cùng tên. Không sao chép các trường nội bộ.

Nếu bạn cần sao chép các trường nội bộ, thực sự không khó thực hiện bằng cách sử dụng javax.lang.reflect.

Các vấn đề liên quan