2016-03-22 8 views
2

TestAとTestBの2つのクラスがあるとします。種皮がTESTBを拡張することとしますKotunctionでのkotlinジェネリック

public class TestB { 
    private int intProp; 
    public int getIntProp() { 
     return intProp; 
    } 
    public void setIntProp(int intProp) { 
     this.intProp = intProp; 
    } 
} 


public class TestA extends TestB { 
    private String strProp; 
    public String getStrProp() { 
     return strProp; 
    } 
    public void setStrProp(String strProp) { 
     this.strProp = strProp; 
    } 
} 

今、私は次のコード行を作成:

var getter1: KFunction1<TestA, Int> = TestA::getIntProp 

あなたが見ることができるように、私はTESTBの種皮クラスメソッドからのアクセス:種皮を:: getIntProp SO結果KFunction1のインスタンスは

は今、私は次のコード行を作成しようとする一般的なのparams <種皮、整数>である

var getter2: KFunction1<TestA, Int> = TestB::getIntProp 

そしてそれはまた、動作し、私はこれがgenerics variance in Kotlinでエラーに

答えて

5

がコンパイルされることを期待しながら、コンパイルが、その目的は、クラス階層そのものであるパラメータを持つジェネリッククラスに、タイプセーフな階層を課すことです。

クラスKFunction1out修飾子とin修飾子とR<in P1, out R>P1として定義されている一般的なパラメータがあります。

  • Contravariance in修飾によって導入P1に:これはあるだろうということを意味します。 PSuperPのスーパータイプである場合

    どれKFunction1<PSuper, R>KFunction1<P, R>のサブタイプになります。しかし、P1は、KFunction1のメンバーの引数としてしか現れないという制限が追加されます。

  • 共変動Rout改変剤によって導入されました。 RSubRのサブタイプである場合

    どれKFunction1<P, RSub>KFunction1<P, R>のサブタイプになります。そしてここにはRが限定されます:KFunction1のメンバーの戻り値として渡すことができます。

したがって、あなたはタイプKFunction1<P, R>の変数にKFunction1<PSuper, RSub>を割り当てることができるようになります。

タイプPSuperの引数を受け取り、任意の機能もPのインスタンスを受信する(ただし、その逆)ことができるので、これは、KFunction1ために理にかなって、同じ時間にRSubのインスタンスを返す任意の関数がRのインスタンスを返します(ただしその逆はありません)。

class Invariant<T> { 
    fun f(i: Int): T { throw Exception() } // OK 
    fun f(t: T): Int { throw Exception() } // OK 
} 

class Contravariant<in T> { 
    fun f(i: Int): T { throw Exception() } // error, T cannot be returned 
    fun f(t: T): Int { throw Exception() } // OK, T is parameter type 
} 

class Covariant<out T> { 
    fun f(i: Int): T { throw Exception() } // OK, T is returned 
    fun f(t: T): Int { throw Exception() } // error, T cannnot be parameter type 
} 

open class Base 
class Derived: Base() 

val i1: Invariant<Base> = Invariant<Derived>() // error 
val i2: Invariant<Derived> = Invariant<Base>() // error 

val n1: Contravariant<Base> = Contravariant<Derived>() // error 
val n2: Contravariant<Derived> = Contravariant<Base>() // OK 

val v1: Covariant<Base> = Covariant<Derived>() // OK 
val v2: Covariant<Derived> = Covariant<Base>() // error 
:あなたは、単にこの動作を示している例を構成することができます


関連する問題