views:

465

answers:

2

I'm writing a class for a binary tree, and in the tree interface this function is defined:

/** Returns an iterable collection of the the nodes. */
    public Iterable<Position<E>> positions();

The problem is that the type of the node is MY class implementing the position interface in the task. Not the interface itself, Position. That is why I'm having trouble returning an iterable list of the nodes.

@Override
    public Iterable<Position<E>> positions() {
     ArrayList<Posisjon<E>> liste = new ArrayList<Posisjon<E>>();
     liste = dumpings(liste,root);
     System.out.println(liste.get(0));
     return (Iterable<Position<E>>) liste.Iterator(); //PROBLEM HERE!
    }

I use a recursive helper function to extract the elements and add them to an ArrayList and then just return the iterator for the list. "liste" here is of type my class "Posisjon" and the expected return for the function is the interface "Position". Why can't I just use return type "Posisjon" since it is implementing interface "Position"? Nor can I change the return type because the return type is specified in the tree interface which I must implement.

Here is the interface "Position" and my class "Posisjon" in case it helps you to understand the problem. (Node interface and Node class if you will).

public interface Position<E> {
  /** Return the element stored at this position. */
  E element();
}


public class Posisjon<E> implements Position<E> {
    private E element;
    private Posisjon<E> parenten;
    private Posisjon<E> rightChildren;
    private Posisjon<E> leftChildren;
    @Override
    public E element() {
     return element;
    }
    public E setElement(E ting){
     E tmpElement = element;
     this.element = ting;
     return tmpElement;
    }
    public Posisjon<E> leftChild(){
     return leftChildren;
    }
    public Posisjon<E> rightChild(){
     return rightChildren;
    }
    public Posisjon<E> parent(){
     return parenten;
    }
    public Posisjon(E element){
     this.element = element; 
    }
    public void setLeftChild(Posisjon<E> ting){
     this.leftChildren = ting; 
    }
    public void setRightChild(Posisjon<E> ting){
     this.rightChildren = ting; 
    }
}
A: 

You should define your method as:

public Iterable<? extends Position<E>> positions();
Superfilin
+1  A: 

You want

public Iterable<? extends Position<E>> positions();

There are very good reasons why Iterable<A> does not extend Iterable<B> when A extends B. The solution in Java is to use wildcards as above.

Kathy Van Stone
This does require me to change the interface, and I'm not allowed to do so. If you know another way to do this, assuming that there must be another way since the task is defined like this, it would be appreciative.
Algific
@data_jepp I suspect then you should implement Iterable/Iterator directly. I can try to come up with an example if need be. I also notices that you are returning an iterator not an iterable (which would be liste itself).
Kathy Van Stone