4

私はジェネリック (および Java、およびスタック オーバーフロー) を初めて使用します。教科書には、ジェネリック バイナリ サーチ ツリーの実装について説明しているポイントがあります (以下の抜粋)。

Comparable インターフェースは一般的なので、次のタイプの要素を検索ツリーに格納することを考えてみましょう:

< T extends Comparable< T>>

これはまだ問題を引き起こします。Dog と Cat の両方がクラス Mammal のサブクラスであり、Mammal クラスが Comparable インターフェースを実装しているとします。ここで、哺乳動物オブジェクトを格納する二分探索木を作成すると、Dog と Cat を追加できますが、実際には互いに比較することはできません。したがって、このソリューションをこの特定の方法で使用すると、非ジェネリック バージョンの Comparable を使用した場合と同じ問題が発生します。より包括的な解決策は、知的に満足できるものではありませんが、ジェネリック型を次のように記述することです。

< T extends Comparable< ? スーパーT>>

この宣言は、要素の比較可能な性質を T の任意のスーパークラスに制限します。

したがって、型パラメーターが である必要がある理由はわかりますが、本では、 s のツリーに、互いにメソッドを呼び出そうとするさまざまなサブタイプが含まれてComparable< T>いる場合、これが問題を引き起こす可能性があると主張しています。ツリー内のおよびオブジェクトの参照型が である場合、とにかくのメソッドを呼び出して ( である)、有効な比較 (レベルのみ) になるのではないでしょうか?MammalcompareTo()CatDogMammalMammalcompareTo()Comparable< Mammal>Mammal

おそらくs がそうでない場合、クラスなどのスーパークラスにフォールバックすることComparable< ? super T>を除いて、それは同じではないので、どのような違いが生じるのかわかりませんか?MammalComparableComparableAnimal

型消去の厄介な結果や、私が思っているように比較が機能しない原因となるものなど、おそらく何かが欠けています。

4

3 に答える 3

3

<T extends Comparable<T>>さて、あなたはそれがこのようなクラスで機能することを理解しています:

class Mammal extends Comparable<Mammal>

Mammalこれで、、Cat:のサブクラスができましたclass Cat extends Mammal。継承により、Catも実装され、あなたが言ったように、それはから継承した方法Comparable<Mammal>により、すべての哺乳類(もちろん猫を含む)と比較することができます。compareTo(Mammal)Mammal

しかし、問題は、が実装されていないためCat、バインドされたものでは機能しないことです。1つのタイプパラメータでしかインターフェイスを実装できないため、 implementを使用してこれを解決することはできません。<T extends Comparable<T>>CatComparable<Cat>CatComparable<Cat>

Catしかし、概念的には、Catsは他のsと比較できるため、リストの並べ替えに問題はありませんCat(より一般的なすべての哺乳類と比較できますが、重要なのは猫と比較できるということです)。したがって、問題は、私たちの限界があまりにも制限的であるということです。

<T extends Comparable<? super T>>この問題を解決し、使用できるようCatにします。PECSルール-プロデューサーextendsコンシューマーを思い出してくださいsuper。さて、Comparableはコンシューマーであり、プロデューサーではありません。これは、タイプTの引数をそのcompareToメソッド(consume)に渡すためですが、メソッドがタイプT(produce)を返す必要はありません。したがって、superワイルドカードが適切です。

于 2012-07-15T21:45:02.607 に答える
2

申し訳ありませんが、これをより明確にするために書き直します

インターフェースを考える

< T extends Comparable<T> >

次に、サブクラス Cat を検討します

Cat extends Comparable<Cat>

Comparable には同じ型が 2 つ必要なため、Dog のような他のクラスがある場合、これは二分探索ツリーの多くのものを破壊します。猫はこのように見えるはずです

Cat extends Comparable<Animal>

著者はこれを次のように変更します。

< T extends Comparable<? super T> >

次のようなオブジェクトを追加できるようになりました

Cat extends Comparable<Animal>

Comparable に入るパラメーターは、クラス自体ではなくスーパークラスでなければならないためです。つまり、哺乳類 -> 動物 -> オブジェクトの可能性がありますが、文字列とは言えません。

于 2012-07-15T15:35:31.210 に答える
0

要点はこれです。 選択するクラスは、パラメーターをIt Selfとして持つ Comparable インターフェースを実装するか、Base クラスを同等のパラメーターとしてクラスに取り込む他のスーパー クラスにする必要があります。

于 2012-07-15T16:31:44.760 に答える