簡體   English   中英

Java集合:將子集合作為父集合傳遞

[英]Java Collections: Pass collection of children as collection of parents

假設我有一個接口和一些類:

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(); }
}

然后我有一組LocalizedButtons,當我打電話

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

我知道這個方法不適用於這個參數。 如果我嘗試在LocalizedButtonsPanel將此方法重載為addComponents(Set<LocalizedButton> buttons) ,我當然會得到類型擦除。

可能是某些模式被遺漏或存在處理此架構以實現正確添加LocalizedButtons集的技巧?


我得到了答案,我想讓我的例子更具體 - 我的實現中有一些驗證器,所以我需要將集合類型也存儲為通用,這是我使用答案得到的簡化代碼:

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(); }
}

在這種情況下,它的工作原理

將addComponents()簽名更改為

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

這樣方法接受Button的子類集。 這樣,您可以將Set<LocalizedButton>作為參數傳遞,因為LocalizedButton擴展了Button ,因此匹配參數Type of Set<? extends Button> Set<? extends Button>

你有

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

應該

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

該列表僅針對不適用於擴展該類型的Object的按鈕類型創建。

參數化類型在Java中不協變。 這很好,否則你就可以將一個狗添加到已經被上傳到List <Animal>的List <Cat>。 您可以在使用地點添加協方差,例如List <? extends Animal>可以分配一個List <Cat>,你不能調用它的add方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM