Lets say we have a program which contains such classes:
public interface AbstractItem {
}
public SharpItem implements AbstractItem {
}
public BluntItem imple
Here are a couple of extra ideas. Leave everything the same, but use this:
interface AbstractToolbox {
public List<? extends AbstractItem> getItems();
}
This basically says that the abstract class' items are an unknown type, but subclasses can make it concrete. This would require you to call getItems()
on a reference of type ExpensiveToolbox or CheapToolbox to be able to retrieve a list that allows you to add items, etc.
ExpensiveToolbox toolbox = new ExpensiveToolbox();
AbstractToolbox absTB = toolbox;
List<? extends AbstractItem> items1 = absTB.getItems(); //fine
List<SharpItem> items2 = absTB.getItems(); //compile error
List<SharpItem> items3= toolbox.getItems(); //fine
Alternatively, you could just type AbstractToolbox:
public interface AbstractToolbox<T extends AbstractItem> {
public List<T> getItems();
}
public ExpensiveToolbox implements AbstractToolbox<SharpItem> {
public List<SharpItem> getItems() { //...
}
public interface AbstractItem
{
}
public class SharpItem implements AbstractItem
{
}
public class BluntItem implements AbstractItem
{
}
public interface AbstractToolbox<T extends AbstractItem>
{
public List<T> getItems();
}
public class ExpensiveToolbox implements AbstractToolbox<SharpItem>
{
private List<SharpItem> items = new ArrayList<SharpItem>();
public List<SharpItem> getItems() { return this.items; }
}
public class CheapToolbox implements AbstractToolbox<BluntItem>
{
private List<BluntItem> items = new ArrayList<BluntItem>();
public List<BluntItem> getItems() { return this.items; }
}
public void doImportantStuff(AbstractToolbox<?> toolbox)
{
List<? extends AbstractItem> items = toolbox.getItems();
for(AbstractItem item : items)
... ;
}
You're probably going to need to take a look at using wildcard types for generics. Here's a quick link: What is PECS (Producer Extends Consumer Super)?
Quick answer: change the type to List<? extends AbstractItem>
Why can't you just assign this?
Imagine the code here...
List<AbstractItem> foo = new ArrayList<SharpItem>();
foo.add(new BluntItem());
The static typing says this should work... but you can't do that! It would violate the ArrayList's type. That's why this is disallowed. If you change it to
List<? extends AbstractItem> foo = new ArrayList<SharpItem>();
you can then do the assignment, but never add anything to the list. You can still retrieve elements from the list, however, as AbstractItems.
Is just using List (bare type) a good solution?
No, definitely not :-p