java迭代器/可迭代子接口
Posted
技术标签:
【中文标题】java迭代器/可迭代子接口【英文标题】:java iterator/iterable subinterface 【发布时间】:2010-11-25 08:53:50 【问题描述】:我有各种类的接口,所有这些都应该实现Iterator,所以我有类似
public interface A extends Iterable<A> ...otherMethods()...
然而,对于具体的类,这意味着我必须使用
public class B implements A public Iterator<A> iterator() ...
当我更喜欢(或至少,我认为我更喜欢)使用 public Iterator<B> iterator() ...
以便类的具体使用可以具有显式类型(以防我想要不在接口中的方法时)是可用的,或者类似的。也许永远不应该出现?或者如果它出现了,那是糟糕的设计?
另一方面是使用迭代器接口
public interface A extends Iterator<A> ...otherMethods()...
具体的类用
编译就好了public class B implements A public B next() ...
什么给了?
【问题讨论】:
有几个答案建议参数化 A,然后让 B 实现 A - 这很有效,我应该提到我之前已经开始工作了。问题是导致使用 AbstractClass卡尔是对的,我的第一个答案没有编译,但这似乎是。不确定这是否正是您想要的。
public interface A<T extends A> extends Iterable<T>
public class B implements A<B>
@Override
public Iterator<B> iterator()
return null;
【讨论】:
我不认为超类型可以使用通配符;至少,这是我的编译器告诉我的。 我以前试过这个,但是在抽象实现过程中需要 AbstractInterface我想这就是你想要的:
public interface A<T extends A<?>> extends Iterable<T>
public class B implements A<B>
public Iterator<B> iterator() ...
【讨论】:
关于您想要一个不需要子类参数化的解决方案的评论:我认为这是不可能的(但是我不是泛型专家)。如果您使用 Iterator 接口,它会起作用,因为在这种情况下,您可以利用协变,而泛型接口不是协变的。请参阅 Angelika Langer 的出色泛型常见问题解答:angelikalanger.com/Articles/Papers/JavaGenerics/…【参考方案3】:具体类可以很好地编译,因为 B 扩展了 A,并且从 Java 5 开始,子类的返回类型可以是超类返回类型的子类。
至于泛型,我遇到了同样的问题,我知道你有两个选择。
一个是参数化A:
public interface A<T extends A> extends Iterable<T>
然后:
public class B implements A<B>
但是,这有一个缺点,即您需要提供 A 的参数,而不是固定它,即使您想要 A:
private class NoOneSees implements A<A>
关于是否真的想要Iterator<B>
的问题,在Iterable的情况下,很可能是更可取的,并且考虑到这些是接口,重新声明参数的需要可能是合理的。如果你开始继承具体的类,它会变得有点复杂,对于除了 Iterable 之外有意义的东西,你可能需要协方差。例如:
public interface Blah<T>
void blah(T param);
public class Super implements Blah<Super>
public void blah(Super param)
public class Sub extends Super
public void blah(Super param)
//Here you have to go with Super because Super is not paramaterized
//to allow a Sub here and still be overriding the method.
同样对于协方差,您不能声明Iterator<A>
类型的变量,然后在其中分配Iterator<B>
,即使B 扩展了A。
另一个选项是基于这样一个事实,即进一步的实现/子类仍将引用 A。
【讨论】:
可以通过将接口声明从 void blah(T param) 更改为 void blah(U param); 来稍微修复 super/sub rabbithole;【参考方案4】:你的设计决定是你自己的,但我想不出任何理由让设计中的每个类都实现 Iterable。必须有某种东西包含在集合中,但实际上并不是集合本身。我会仔细研究基本设计。也许某些可迭代对象会希望返回与其自身无关的事物的迭代器。
【讨论】:
【参考方案5】:其他答案具有正确的要点 - 但您将通过将泛型类型声明为来获得正确的机制
A<T extends A<T>>
这会强制类返回其自身类型或更低类型的迭代器 - 这样您就可以声明
class B implements A<B>
但不是
class B implements A<A>
我怀疑它更接近你想要的(即实现必须返回迭代器而不是简单地超过 A
s)。
请注意,您对Iterator
和Iterable
的体验源于缺乏泛型类型的协方差; B
的实例是A
,但Iterator<B>
不是Iterator<A>
。
【讨论】:
以上是关于java迭代器/可迭代子接口的主要内容,如果未能解决你的问题,请参考以下文章