Reputation: 114
I'm trying to write an interface that is iterable and supports multiple levels of abstraction. I'm having trouble correctly defining the interface.
I've declared the following interfaces and classes (a toy example):
public interface A {}
public class B implements A {}
public interface C <T extends A> extends Iterable<T> {}
public class D implements C<B> {
public Iterator<B> iterator() { ... }
}
The following works:
D d = new D();
for (A a : d) {}
for (B b : d) {}
But the following does not compile. Java says the for-each loop variable should be of type Object.
C c = new D();
for (B b : c) {}
I know I can cast to appease the compiler in the second example, but that seems yucky. Is there any way to declare interface C and subclass D so that I can support both iteration scenarios, or is that not possible? Thanks!
Upvotes: 2
Views: 36
Reputation: 178253
You're using the raw form of the C
interface when you assign the new D
to c
. Using the raw form of the interface forces type erasure on everything in the interface, meaning that the Iterator
returned in the foreach loop returns Object
s, not B
s.
But C
takes a type argument that must still be supplied, even if D
isn't itself generic. Try
C<B> c = new D();
Upvotes: 5