2016-02-16 8 views
6

一般的なコードを書き込もうとしましたが、Type of 'PROPERTY' is not a subtype of the overridden propertyエラーを取り除くことはできません。Kotlin:サブタイプ内の汎用プロパティをオーバーライド

私のコードの簡易版:

abstract class BaseP<V> { 
    var view: V? = null 
} 

abstract class BaseF { 
    fun smth() { 
     pp.view = this 
    } 
    abstract val pp: BaseP<BaseF> 
} 

abstract class SubF: BaseF() { 
    abstract override val pp: BaseP<SubF> 
    // Error:(20, 30) Type of 'pp' is not a subtype of the overridden property 'public abstract val pp: BaseP<BaseF> defined in BaseF' 
} 

私はそのエラーが@Suppress -edすることができますが、私はそれが最善かつ唯一の方法である疑いが分かりました。何か良いことがありますか?

私は理解できませんが、なぜsubtypeA<subtypeB>baseA<baseB>のサブタイプとしてカウントされません、誰かがこれを説明することができますか?

+0

どの行がエラーをスローしますか? – voddan

答えて

7

まず、SubtypeA<B>BaseA<B>のサブタイプです。問題はジェネリックパラメータのサブタイプにあります。

答えはKotlin generics varianceにあり、これはthat of Javaに似ています。

なぜBaseA<BaseB>のサブタイプとしてSubtypeA<SubtypeB>カウントはしないのですか?

ジェネリックは、そうでなければ分散調整剤in及びout(又はJava wildcards)で指定されない限り、さらに簡単場合には、クラスA<T>ため、A<SubtypeB>A<BaseB>が互いのサブタイプではない、ことを意味する、デフォルトでは不変です。

2つのケースが考えられますA<out T>

  • あなただけにしたいなら、あなたはout修飾子を使用することができ、あなたのクラスAのインスタンスのうち、Tインスタンスを取ります。

    A<SubtypeB>A<SubtypeB>から明らかにBaseBのインスタンスを取ることができ、その逆もありませんので、のサブタイプになります。

  • あなたのクラスのメソッドにのみにパスTをしたい場合は、あなたのクラス宣言でin修飾子を使用します。A<in T>が。 A<BaseB>のすべてのインスタンスがまたその逆の方法にSubtypeBを受け取ることはできませんが、ため

    そしてここでA<BaseB>は、A<SubtypeB>のサブタイプです。

あなたの両方に合格し、自分のクラスA<T>からに/ Tを取る場合は、その後、Tのための唯一の選択肢は、それA<SubB>A<SuperB>どちらもA<B>のサブタイプがあるように、不変であることです。そうでない矛盾につながります上記に。

そしてこれがまさにそうである:あなたのBaseP<B>に、あなたは両方のVのアイテムを取っているとviewプロパティにものを入れて、そのVのみ不変とすることができ、BaseP<SubF>BaseP<BaseF>のサブタイプではないではありません、どちらもSubP<SubF>です。

関連する問題