====== 共変_反変 ====== Kotlinの場合 不変(Array)...同じ型でなければならない。(そもそもlistは不変ではない) 共変(out)...上位の型に下位の型を入れることが出来る。  設定といっても初期値(val)として。  取り出す(参照)ときには上位の型として取り出す。 反変(in)...下位の定義を上位の定義を設定できる。  設定とはvar変数に値をいれること。  参照するときは上位の型として参照する。   ===== 不変 ===== fun main() { // --- 不変 ... 同じ型でなければならない --- // listは不変ではない val intList = listOf(1, 2, 3) val anyList: List = intList // 配列は不変 val intArray = Array(3,{index -> index}) // val anyArray:Array = intArray // 方が違うのでコンパイルエラー ===== 共変(out) ===== valとして変更しない、参照用(out)として値を設定する 上位のAny型に、下位のint型を設定しているが、Any型として参照しかしない(out)ので安全。 // --- 共変(out) ... 広い定義に狭い定義のものを参照用に入れることが出来る(val)  --- // --- 提供するだけ 戻り値として広い定義を使用できる val intArray2 = Array(3,{index -> index}) val anyArray2:Array = intArray2 // outがないとコンパイルエラー val tmp2 = anyArray2[2] // outとしてはAny?型となる if(tmp2 is Any?){ println("temp2 is Any") }else{ println("temp2 is not Any") }  ↓   temp2 is Any ===== 反変(in) ===== varの値を変更する。 下位のHuman型の配列に、上位のAnimal型の配列を設定しているが、Animal型としてしか参照しないので安全。 // --- 反変 ... val intArray3 = Array(3,{index -> index*3}) var anyArray3:Array = intArray3 anyArray3.forEach { println("anyArray3=${it}")} // --- 反変2 クラス これはできて当たり前 open class Animal(val name:String){ open fun Cry(){println("${name}!!")} } class Human(name:String):Animal(name){ override fun Cry(){println("I'm${name}")} } val animal:Animal = Human("Takeshi") // クラスは共変 animal.Cry() // --- 反変2 クラス配列 これが本当の反変 val humanArray:Array = Array(1, {i -> Animal("Gray")}) // Human型にAnimalが入る // val animal2:Human = humanArray[0] as Human // Human型だとコンパイルでエラーとなる // animal2.Cry() // エラーとなる val animal3:Animal = humanArray[0] as Animal // Animal型だと取り出せる。 animal3.Cry() // Animal型として使える } ===== Listの場合 ===== listはそもそも不変ではない。 val intList = listOf(1,2,3) val strList= listOf("a","b","c") val anyList:List = intList + strList anyList.forEach { println(it) } ↓ 1 2 3 a b c val anyList2 = listOf("a","b","c") // val intList2:List = anyList2 コンパイルエラー