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>
)?
答案 0 :(得分:3)
您应该使用:
val myClass: AbsClass<out Any> = MyClass()` or `val myClass: AbsClass<in Nothing> = MyClass()
out
关键字意味着您希望将任何子类型分配给超类型。 MyModel
可以分配给Any,所以可以。
in
关键字意味着您希望可以将任何超类型分配给子类型(在本例中为Nothing),因此可以使用MyModel
,因为它是Nothing
的超类型。 / p>
我认为,这样一来,如果不提供任何预期类型的信息(您可以指定类似AbsClass<T : MyAbstractModel>
的信息),那么在不进行强制转换或反射的情况下,几乎没有任何可能性。
这是类型差异,它是OOP中最困难的想法之一。您可以在这里阅读更多内容: https://kotlinlang.org/docs/reference/generics.html#variance