2016-03-30 32 views
2

はのは、私は一般的なクラスがあるとしましょう:もちろん一般的な境界

class OrderedArray<T>(
    private val items: Array<T>, 
    private val comparator: Comparator<in T> 
) { 
    constructor(items: Array<T>) : this(items, naturalOrder<T>()) 
} 

Tが必ずしも同等ではないとして、このコードはコンパイルされません。コンストラクタ上の型のジェネリックパラメータを束縛する言語構造が利用可能ですか?自然順序付けが可能なときに、コンパレータを明示的に渡すことなくクラスのインスタンスを構築する方法を教えてください。

答えて

4

コンストラクタに独自のジェネリックパラメータがなく、クラスパラメータのみを使用できるため、コンストラクタにジェネリックバウンドを導入する方法はありません。 だけで上書きするクラスを作成し(

class NaturallyOrderedArray<T: Comparable<T>>(items: Array<T>) 
    : OrderedArray<T>(items, naturalOrder<T>()) 

をしかし、それは不器用になります

  • 一つの解決策は、一般的なバウンドでサブクラスを作り、それを使用することです:

    は次の回避策を検討しますジェネリックバインドを作成し、別のコンストラクタを導入しますか?)、親クラスはopenまたは少なくともsealedである必要があります。

  • あなたが希望ジェネリックバウンドでファクトリ関数を行うことができます。

    fun <T: Comparable<T>> naturallyOrderedArray(items: Array<T>) = 
        OrderedArray(items, naturalOrder<T>()) 
    

    あなたはそれがOrderedArray(items)のように呼ばれることになるように、関数がコンストラクタを模倣しますが、自然なこともほのめかしうit's better to keep to consistent namingかもしれません注文が使用されます。

1

私は海峡-前方に記述します。

class OrderedArray<T: Comparable<T>>(
    private val items: Array<T>, 
    private val comparator: Comparator<in T> = naturalOrder<T>()) 

は、それが問題を解決していますか?そうでない場合、あなたの場合の制限は何ですか?

+0

私のクラスは、匹敵していないT-sでもうまく働きたいと思っています。もちろん、これらのケースでは明示的なコンパレータを提供する必要があります。 –