2010-08-03 33 views
7

Nói rằng tôi có một giao diện và một số lớp học:Java Collections: Thu thập đèo trẻ em như bộ sưu tập của cha mẹ

public interface IPanel<ComponentType extends Component> { 
    public void addComponents(Set<ComponentType> components); 
    public ComponentType create(); 
} 

public class Button extends Component { } 

public class LocalizedButton extends Button { } 

public class ButtonsPanel implements IPanel<Button> { 
    public void addComponents(Set<Button> components) { ... /* uses create() */ ; } 
    public Button create() { return new Button(); } 
} 

public class LocalizedButtonsPanel extends ButtonsPanel { 
    public Button create() { return new LocalizedButton(); } 
} 

Sau đó, tôi có một bộ LocalizedButtons và khi tôi gọi

final LocalizedButtonsPanel localizedButtonsPanel = new LocalizedButtonsPanel(); 
final Set<LocalizedButton> localizedButtonsSet = new LinkedHashSet<LocalizedButton>(); 
localizedButtonsPanel.addComponents(localizedButtonsSet); 

tôi nhận được rằng phương thức này không áp dụng cho các đối số này. Nếu tôi cố gắng quá tải phương pháp này là addComponents(Set<LocalizedButton> buttons) trong LocalizedButtonsPanel, tôi sẽ xóa được loại, tất nhiên.

Có thể một số mẫu bị bỏ qua hoặc thủ thuật tồn tại để đối phó với kiến ​​trúc này để thực hiện chính xác việc thêm tập hợp LocalizedButtons?


Tôi đã có câu trả lời và tôi muốn thực hiện ví dụ của tôi cụ thể hơn - Tôi có một số xác nhận trong việc thực hiện của tôi, vì vậy tôi cần phải loại bộ sưu tập để cũng được lưu trữ như chung, đó là đơn giản hóa mã tôi đã có sử dụng câu trả lời:

public interface IPanel<ComponentType extends Component, CollectionType extends Collection<? extends Component>> extends Validated<CollectionType> { 
    public void addComponents(CollectionType components); 
    public ComponentType create(); 
} 

public class Button extends Component { } 

public class LocalizedButton extends Button { } 

public class ButtonsPanel implements IPanel<Button, Set<? extends Button>> { 
    public void addComponents(Set<? extends Button> components) { ... /* uses create() */ ; } 
    public Button create() { return new Button(); } 
} 

public class LocalizedButtonsPanel extends ButtonsPanel { 
    public Button create() { return new LocalizedButton(); } 
} 

Và trong trường hợp này, nó hoạt động

+0

có (có thể là) một câu hỏi tương tự http://stackoverflow.com/questions/298305/, nhưng câu trả lời có phá vỡ giao diện tôi có –

Trả lời

6

Thay đổi addComponents() chữ ký để

public void addComponents(Set<? extends Button> components) 

để các phương pháp chấp nhận bộ lớp con của Button. Bằng cách này, bạn có thể vượt qua một đối số Set<LocalizedButton>, vì LocalizedButton kéo dài Button và do đó khớp với thông số Loại Set<? extends Button>.

+0

Ồ vâng, cảm ơn.Cấu trúc của tôi phức tạp hơn một chút (tôi sẽ mô tả trong câu hỏi), nhưng tôi đã sửa chữa generics của tôi để phù hợp với tư vấn của bạn và nó thực sự phù hợp :). –

5

Bạn có

public class ButtonsPanel implements IPanel<Button> { 
    public void addComponents(Set<Button> components) { ... /* uses create() */ ; } 
    public Button create() { return new Button(); } 
} 

Phải là

public class ButtonsPanel implements IPanel<Button> { 
    public void addComponents(Set<? extends Button> components) { ... /* uses create() */ ; } 
    public Button create() { return new Button(); } 
} 

Danh sách này chỉ được tạo cho loại nút không dành cho đối tượng mở rộng loại đó.

+1

điều này: 'lớp công khai ButtonsPanel triển khai IPanel ' sẽ không làm việc, bởi vì ký tự đại diện không được hỗ trợ trong' phần implements', và nếu tôi chỉ định này: 'public class GenericButtonsPanel thực hiện Ipanel ' sau đó' LocalizedButtonsPanel kéo dài GenericButtonsPanel < LocalizedButton> 'trong trường hợp này sẽ không phải là con của' ButtonsPanel' mà 'mở rộng GenericButtonsPanel

+1

Đúng, tôi đã chỉnh sửa bài đăng của mình. –

0

Các loại tham số không phải là biến thể trong Java. Điều này là tốt, nếu không bạn sẽ có thể thêm một con chó vào một danh sách <Cat> đã được upcast vào Danh sách <Animal>. Bạn có thể thêm hiệp phương sai tại trang web sử dụng, ví dụ: Danh sách <? extends Animal > có thể được chỉ định một Danh sách <Cat> và bạn không thể gọi phương thức thêm của nó.

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