Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generifying with "super"

Tags:

java

generics

I would like to write an Interator like this:

class Plant { }
class Tree extends Plant { }
class Maple extends Tree { }

// Iterator class: compiler error on the word "super".
class MyIterator<T super Maple> implements Iterator<T> {
    private int index = 0;
    private List<Maple> list = // Get the list from an external source.

    public T next() {
         Maple maple = list.get(index++);
         // Do some processing.
         return maple;
    }

    // The other methods of Iterator are easy to implement.
}

Conceptually, the idea is to have an iterator that looks like it returns Trees or Plants (even though they are always Maples) without writing separate classes for each.

But the compiler doesn't like it when I generify with T super Maple; apparently you can only generify a class using T extends Something. Does anyone know of a good way to accomplish the same thing?

My motivation for asking is that I have a program that uses interfaces for its API. I want to have one method that returns an iterator of interfaces (for the API) and another that returns an iterator of the implementation classes (for internal use).

like image 876
Dan R. Avatar asked May 03 '12 20:05

Dan R.


2 Answers

See: Why is there no lower bound for type parameters?

like image 119
Michael Brewer-Davis Avatar answered Sep 25 '22 12:09

Michael Brewer-Davis


If Maple is a Tree and a Plant, because it extends both, what is the point then in the super clause that you want to use? You can, by classical subtype polymorphism assign Mapple to Object, to Tree or to Plant references.

Both ? extends T and ? super T are wildcards, declared as type arguments to substitute a type parameter T.

What you intend to do is define the bound of a type argument not of the type parameter. You can simply declare your type parameter as T, with no bounds, and then, when you use it, you use a wildcard as the type argument.

class MyIterator<T> implements Iterator<T> { ... }

And when you use it:

MyIterator<? super Maple> iter;
like image 40
Edwin Dalorzo Avatar answered Sep 25 '22 12:09

Edwin Dalorzo