apoorv020
apoorv020

Reputation: 5660

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 EightQueenSolutionSpace 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.

Upvotes: 1

Views: 1722

Answers (7)

duffymo
duffymo

Reputation: 308938

return new HashSet<ISolutionSpace>();

All the references in the HashSet can point to EightQueenSolutionSpace instances, but the generic type should be ISolutionSpace.

Upvotes: 1

orange
orange

Reputation: 1

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.

Upvotes: 0

Riduidel
Riduidel

Reputation: 22300

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>();
}

Upvotes: 3

Sanjay T. Sharma
Sanjay T. Sharma

Reputation: 23218

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()

Upvotes: 0

Axel Fontaine
Axel Fontaine

Reputation: 35167

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.

Upvotes: 10

npinti
npinti

Reputation: 52185

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

Upvotes: 0

G B
G B

Reputation: 3024

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...)

Upvotes: 0

Related Questions