2

代码片段

fun main() {
    val myClass : AbsClass<Any> = MyClass()
    // Error - type mismatch

    val myClass : AbsClass<*> = MyClass() 
    // Not Error, but parameter of 'foo' is 'Nothing'

    val myClass : AbsClass<Any> = MyClass() as AbsClass<Any> 
    // It's correct works with unchecked cast warning and unnecessary casting code.

    myClass.foo(MyModel())
}

class MyClass() : AbsClass<MyModel>() {
}

abstract class AbsClass<T> {
    fun foo(value:T){}
}

data class MyModel(val number:Int = 0)

问题

我想编写代码,val myClass : AbsClass<Any> = MyClass()但是它显示类型不匹配错误。如何解决这个问题(避免类型转换代码as AbsClass<Any>)?

4

1 回答 1

8

你应该使用:

val myClass: AbsClass<out Any> = MyClass()` or `val myClass: AbsClass<in Nothing> = MyClass()

out关键字意味着您希望任何子类型都可以分配给超类型。MyModel可以分配给任何,所以没关系。

关键字意味着您希望任何超in类型都可以分配给子类型(在我们的示例中为 Nothing),因此您可以使用 your MyModel,因为它是Nothing.

这样,在不提供任何预期类型的​​信息(您可以指定,如AbsClass<T : MyAbstractModel>)的情况下,在我看来,没有强制转换或反射的可能性真的很小。

这是类型差异,它是 OOP 中最困难的想法之一。您可以在这里阅读更多内容: https ://kotlinlang.org/docs/reference/generics.html#variance

于 2019-03-05T09:21:45.410 回答