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
Change the addComponents() signature to
public void addComponents(Set<? extends Button> components)
so that the methods accepts sets of subclasses of Button.
This way, you can pass a Set<LocalizedButton>
as an argument, because LocalizedButton
extends Button
and therefore matches the parameter Type of Set<? extends Button>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With