Ideally, it would look like this (the context doesn't matter):
public interface myInterface extends Iterable<Point>, Iterable<Segment> { ... }
But this is not allowed in Java. How can I achieve this behaviour?
Ideally, it would look like this (the context doesn't matter):
public interface myInterface extends Iterable<Point>, Iterable<Segment> { ... }
But this is not allowed in Java. How can I achieve this behaviour?
Unfortunately you cannot. In Java you cannot have two methods with following signatures:
Iterator<Point> iterator();
Iterator<Segment> iterator();
in one class or interface.
As other said before, this is impossible. Better use delegation instead of multiple implementation like this:
public interface MyInterface {
Iterable<Point> points();
Iterable<Segment> segments();
}
So you can iterate using for:
MyInterface my = ...;
for (Point p : my.points()) {
...
}
for (Segment s : my.segments()) {
...
}
You cannot. Due to type erasure, in the bytecode, and therefore at run time, Iterable<Whatever>
becomes Iterable
.
So, at run time, your class' prototype would be:
public interface myInterface extends Iterable, Iterable { ... }
Considering that, how do you determine what class was meant to be iterated over?
As a possible workaround, you could create interfaces for the iterations you want.
public interface SegmentIterable{
public Iterator<Segment> segmentIterator();
}
public interface PointIterable{
public Iterator<Point> pointIterator();
}
It's not ideal, but would be passable as long as you had a limited number of things you wanted to iterate over.
Others have said it is impossible. They are wrong. It is possible, but probably not what you want.
public interface MyInterface<T extends Point & Segment> extends Iterable<T>
{
}
If what you are iterating extends both point and segment this will work. Otherwise Type Erasure means this won't work.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.5
A class may not at the same time be a subtype of two interface types which are different invocations of the same generic interface (§9.1.2), or a subtype of an invocation of a generic interface and a raw type naming that same generic interface, or a compile-time error occurs.
Instead of inheriting from the iterable types, try something like this:
public interface MyInterface {
public Iterable<Point> asPoints() { ... }
public Iterable<Segment> asSegments() { ... }
}
Then when you want to iterate, it's simply a matter of:
for (Point p : myClass.asPoints()) {
...
}
This is a pretty common practice, as seen in the Java Collections class.
You can also consider creating common interface, superclass or wrapper for Point and Segment and use it as a generic parameter.