Returning a collection of interfaces
I have created the following interface
public interface ISolutionSpace {
public boolean isFeasible();
public boolean isSolution();
public Set<ISolutionSpace> generateChildren();
}
However, in the implementation of ISolutionSpace
in a class called EightQueenSolutionSpace
, I am going to return a set of EightQueenSolutionSp开发者_JAVA百科ace
instances, like the following stub:
@Override
public Set<ISolutionSpace> generateChildren() {
return new HashSet<EightQueenSolutionSpace>();
}
However this stub wont compile. What changes do I need to make?
EDIT: I tried 'HashSet' as well and had tried using the extends keyword. However since 'ISolutionSpace' is an interface and EightQueenSolutionSpace
is an implementation(and not a subclass) of 'ISolutionSpace', it is still not working.
Two possibilities:
@Override
public Set<? extends ISolutionSpace> generateChildren() {
return new HashSet<EightQueenSolutionSpace>();
}
Or
@Override
public Set<ISolutionSpace> generateChildren() {
return new HashSet<ISolutionSpace>();
}
and simply add instances of EightQueenSolutionSpace to the set.
Mind you, inheritance and other object hierarchy features don't exactly work like expected in generics.
But it's not your only problem : you try to return an ArrayList
as an implementation of Set
, which can't work !
Concerning the generics part, when you write Set<ISolutionSpace>
, you say to the compiler you want a collection of instances of ISolutionSpace
, but not of possible subclasses of ISolutionSpace
. To be allowed to use subclasses, you'll have to use ? extends ISolutionSpace
, which precisely says "accept any subclass of ISolutionSpace".
So, to have a valid code, you'll have to change both your interface and your implementation.
Your interface should become
public interface ISolutionSpace {
public boolean isFeasible();
public boolean isSolution();
public Set<? extends ISolutionSpace> generateChildren();
}
And your implementation
@Override
public Set<? extends ISolutionSpace> generateChildren() {
//for()
return new HashSet<EightQueenSolutionSpace>();
}
return new HashSet<ISolutionSpace>();
All the references in the HashSet can point to EightQueenSolutionSpace instances, but the generic type should be ISolutionSpace.
Set and List are different types of collections.
You could either change your declaration to return a list, or change the return parameter class to an implementation of Set (HashSet, TreeSet...)
According to the Java API:
Interface Set
All Superinterfaces: Collection All Known Subinterfaces: SortedSet All
Known Implementing Classes: AbstractSet, HashSet, LinkedHashSet, TreeSet
I think you have to replace Set with List:
Interface List
All Superinterfaces: Collection
All Known Implementing Classes: AbstractList, ArrayList, LinkedList, Vector
Assuming the caller would in turn work with the generic ISolutionSpace
interface rather than the specific EightQueenSolutionSpace
, just change the generateChildren
method to public Set<? extends ISolutionSpace> generateChildren()
All the types of collection in Java is like this:
Collection
├List
│ ├LinkedList
│ ├ArrayList
│ └Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
So it's obvious for this error. Try modify Set into List would solve this problem.
Hope this would help you.
精彩评论