4

我有各种类的接口,所有这些都应该实现迭代器,所以我有类似的东西

public interface A extends Iterable<A> { ...otherMethods()... }

然而,对于具体的类,这意味着我必须使用

public class B implements A { public Iterator<A> iterator() {...} }

当我更喜欢(或至少,我认为我更喜欢)使用public Iterator<B> iterator() {...}时,以便类的具体使用可以具有显式类型(以防我希望接口中没有的方法可用,或者一些这样的. 也许这永远不应该出现?或者如果它出现了它的糟糕设计?

另一方面是使用 Iterator 接口

public interface A extends Iterator<A> { ...otherMethods()... }

具体类编译得很好

public class B implements A { public B next() {...} }

是什么赋予了?

4

5 回答 5

2

卡尔是对的,我的第一个答案没有编译,但这似乎是。不确定它是否正是您想要的。

public interface A<T extends A> extends Iterable<T> {

}

public class B implements A<B> {

    @Override
    public Iterator<B> iterator() {
        return null;
    }
于 2009-09-03T17:00:27.297 回答
1

具体类编译得很好,因为 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。

于 2009-09-03T17:22:53.900 回答
1

其他答案具有正确的要点-但是通过将泛型类型声明为,您将获得正确的机制

A<T extends A<T>>

这会强制一个类返回一个属于其自身类型或更低类型的迭代器 - 因此您可以声明

class B implements A<B>

但不是

class B implements A<A>

我怀疑这更接近你想要的(即实现必须返回迭代器而不是简单地超过As)。

请注意,您对Iteratorvs的体验Iterable源于缺乏泛型类型的协方差;的一个实例B 一个A但一个Iterator<B>不是一个。Iterator<A>

于 2009-09-08T15:09:48.197 回答
0

我想这就是你想要的:

public interface A<T extends A<?>>  extends Iterable<T>

public class B implements A<B> {
  public Iterator<B> iterator() {...}
}
于 2009-09-03T17:18:15.000 回答
0

你的设计决定是你自己的,但我想不出任何理由让设计中的每个类都实现 Iterable。必须有某种东西包含在集合中,但实际上并不是集合本身。我会仔细研究基本设计。也许某些可迭代对象会想要返回与自身无关的事物的迭代器。

于 2009-09-03T20:02:30.837 回答