Say I have an interface and some classes:
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(); }
}
Then I have a set of LocalizedButtons and when I call
final LocalizedButtonsPanel localizedButtonsPanel = new LocalizedButtonsPanel();
final Set<LocalizedButton> localizedButtonsSet = new LinkedHashSet<LocalizedButton>();
localizedButtonsPanel.addComponents(localizedButtonsSet);
I get that this method is not applicable for this arguments.
If I try to overload this method as addComponents(Set<LocalizedButton> buttons)
in LocalizedButtonsPanel
, I get type erasure, of course.
May be some pattern is missed or the trick exists to deal with this architecture to implement correct adding the set of LocalizedButtons?
I've got the answer and I want to make my example more concrete - I have some validators in my implementation, so I need the collection type to be also stored as generic, that is simplified code I've got using the answer:
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(); }
}
And in this case, it works