Re: iterator over superclass of collection
Hendrik Maryns <hendrik_maryns@despammed.com> writes:
Frank Fredstone schreef:
Chris Smith <cdsmith@twu.net> writes:
Frank Fredstone <none@not.no> wrote:
I mean just use the iterator straight from the vector:
public Iterator<? extends Aye> iterator() {
return ayes.iterator();
}
But then that wouldn't match Iterable<Aye>.
The important point here is that you REALLY want a value of the more
general type Iterable<? extends Aye>, and not an Iterable<Aye>. That
more general type correctly expresses the idea you want: namely, an
Iterable that returns elements which are assignment-compatible with Aye.
But that isn't what I want. Here is the scenario again. I have a class
that is a collection of instances of an interface, it is an iterable
collection of Ayes.
In the collection class I want to have a private implementation of
that interface. Below, my class can't extend a wildcard capture, and I
really don't want it to, because people aren't supposed to be able to
create instances of the interface, nor are they supposed to set
anything in the collection.
It???s not because it extends a wildcard capture that people will suddenly
be able to create instances of the interface or set anything. You allow
them to if you provide them the methods.
I can't sub-class a wildcard capture, so that makes it true that the
iterator method of the Iterable can't be Iterator<? extends Aye>, I
think.
Below is the code I have. My question is still if there is something,
probably involving wildcards that would make it so that I don't have
to create an anonymous iterator class in my iterator method below. My
motivation is to clear up what looks like it could be a gap in my
understanding of generics.
I suggest you read the Java generics document about wildcards once more.
They really aren???t evil.
import java.util.Iterator;
import java.util.Vector;
Consider using ArrayList, see the thread Efficiency -- Vectors above.
public class X implements Iterable<Aye> {
private class PrivateAye extends A implements Aye {
private int code = 0;
public PrivateAye(String eh, int n) {
super(eh);
setCode(n);
}
public int getCode() { return code; }
public void setCode(int n) { code = n; }
public String aye() { return a(); }
}
private Vector<PrivateAye> ayes;
private ArrayList<Aye> would suffice here, from what you do with it below.
Otherwise, what is your problem with using ArrayList<? extends Aye>
here? It is private anyway, so nobody can do anything with it.
If I take your meaning, it only changes where some assignments are put.
Either what I have already, or:
// or arraylists
private Vector<PrivateAye> realAyes;
private Vector<? extends PrivateAye> ayes;
public void go() throws Exception {
realAyes = new Vector<PrivateAye>();
realAyes.add(new PrivateVector("a", 0));
realAyes.add(new PrivateVector("b", 1));
ayes = realAyes;
}
And one line deleted from the iterator method:
public Iterator<Aye> iterator() {
return new Iterator<Aye>() {
private Iterator<? extends Aye> it = ayes.iterator();
public boolean hasNext() { return it.hasNext(); }
public Aye next() { return it.next(); }
public void remove() { it.remove(); }
};
}
You???ll have to explain what you need the PrivateAye class for, to make
the point clearer.
What I need PrivateAye for is to demonstrate a scenario where I need
to have an iterable of interfaces where the actual implementation is
private. I'm posing the scenario in order to ask the question:
Is there something, probably involving wildcards that would make it so
that I don't have to create an anonymous iterator class in my iterator
method of the iterable (where the iterable is of instances of
interfaces which are implemented by private classes).
None of these are answers to the question:
1. Don't do that.
2. Why are you doing that?
3. Use this instead.
Though those can be interesting too.
My motivation is to clear up what looks like it could be a gap in my
understanding of generics, not to have a solution given to me for some
immediately practical purpose.