Свойство родового класса Kotlin
Я знаю, что это может показаться повторяющимся вопросом, но я озадачен тем, как работают инвариантность, ковариация и контравариантность.
Я не могу понять, почему я не могу скомпилировать этот фрагмент:
class Test<X: List<Any>>{
lateinit var list2:List<Any>
lateinit var list1:X
fun putList(){
list2 = emptyList()
list1 = emptyList<Any>()
}
}
Я получаю ошибку несоответствия типов Обязательный X найден Список
Однако, если я определю универсальный X как 'out', я получу ошибку, указывающую, что параметр X инвариантен в list1 var.
Может ли кто-нибудь помочь другой бедной душе, потерянной в дженериках Kotlin?
1 ответ
Краткий ответ: вар list1
является ковариантным, вы пытаетесь использовать его контравариантным образом.
Что вы сейчас пытаетесь сделать: назначить экземпляр супертипа (указан верхней границей) List<Any>
к переменной своего подтипа X
, который list1
, Чтобы упростить проблему, рассмотрите следующее:
open class Super
class Sub : Super()
val sub: Sub = Super() //Compile Error: Type mismatch: inferred type is Super but Sub was expected
Вы просто не можете назначать объекты переменным подтипа этого объекта. И наоборот, было бы хорошо: val sup: Super = Sub()