开发者

Returning a collection of interfaces

开发者 https://www.devze.com 2023-02-04 21:25 出处:网络
I have created the following interface public interface ISolutionSpace { public boolean isFeasible(); public boolean isSolution();

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消