[英]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.