4

さまざまなクラスのインターフェイスがあり、そのすべてが Iterator を実装する必要があるため、次のようなものがあります

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 以降では、サブクラスの戻り値の型をスーパークラスの戻り値の型のサブクラスにすることができるため、具体的なクラスは正常にコンパイルされます。

ジェネリックに関しては、私は同じ壁にぶつかりました。私が知っている 2 つの選択肢があります。

1 つは、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.
}

共分散についても同様に、B が A を拡張したとしても、型の変数を宣言してIterator<A>からそれに an を代入することはできません。Iterator<B>

他のオプションは、さらなる実装/サブクラスが引き続き A を参照するという事実とともに有効です。

于 2009-09-03T17:22:53.900 に答える
1

他の答えには正しい要点がありますが、ジェネリック型を次のように宣言することで、正しいメカニズムを得ることができます

A<T extends A<T>>

これにより、クラスは独自の型以下のイテレータを返すように強制されるため、次のように宣言できます。

class B implements A<B>

だがしかし

class B implements A<A>

これはあなたが望むものに近いと思います(つまり、実装は単に s ではなく、それ自体で反復子を返す必要がありますA)。

Iteratorvsの経験はIterable、ジェネリック型の共分散の欠如に起因することに注意してください。のインスタンスはB ですAが、はIterator<B>ではありませIterator<A>

于 2009-09-08T15:09:48.197 に答える
0

あなたのデザインの決定はあなた自身のものですが、デザインのすべてのクラスが Iterable を実装する理由は考えられません。コレクションに含まれているものの、実際にはコレクション自体ではない何かがあるはずです。基本的な設計をじっくりと検討します。一部のイテラブルは、それ自体に関係のないもののイテレータを返したい場合があります。

于 2009-09-03T20:02:30.837 に答える
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 に答える