如何正确地覆盖返回Kotlin中的泛型类实例的方法

我有一个抽象的泛型类:

abstract class BasePresenter<View, Router> { var view: View? = null var router: Router? = null abstract fun OnStart() abstract fun OnStop() } 

我有它的一个子类:

 class NewsListPresenter : BasePresenter<NewsListView, MainRouter>() { override fun OnStop() { // } override fun OnStart() { // } } 

另外我有一个受保护的抽象方法的类:

 protected abstract fun getPresenter() : BasePresenter<Any?, Any?> 

我把它覆盖在一个子类中:

 override fun getPresenter(): BasePresenter<Any?, Any?> { return NewsListPresenter() as BasePresenter<Any?, Any?> } 

Android Studio突出显示了重写的功能强制转换,说“这个转换不会成功”。 我尝试使用in Anyout Any* ,它不起作用。 当我尝试使用*我无法在最初定义的类中使用getPresenter()方法。 Android Studio抱怨类型不匹配:required Nothing ?,找到BaseFragment。 在Java中,相同的代码可以完美工作,我不认为这是Kotlin的问题。 什么是正确的方式来实现这个?

在这里“铸造不能成功”的警告是不正确的。 警告的正确信息应该是“未经检查的强制转换”,因为这个转换可能是正确的,但不能通过运行程序来发现。

追踪器中有一个问题 ,实际上前几天已经修复了。 修复将可能使它对Kotlin 1.0.3。

使用BasePresenter<*,*>

从文档 :

星预测

有时候你想说,你对类型参数一无所知,但仍然想要以一种安全的方式使用它。 这里的安全方法是定义泛型类型的投影,使得泛型类型的每个具体实例都是该投影的子类型。

Kotlin为此提供了所谓的星形投影语法:

对于Foo<out T> ,其中T是具有上限TUpper的协变类型参数, Foo<*>相当于Foo<out TUpper> 。 这意味着当T未知时,可以安全地从Foo<*>读取TUpper值。 对于Foo<in T> ,其中T是逆变类型参数, Foo<*>相当于Foo<in Nothing> 。 这意味着当T未知时,您可以以安全的方式写信给Foo<*> 。 对于Foo<T> ,其中T是具有上限TUpper的不变类型参数, Foo<*>相当于读取值的Foo<out TUpper> ,以及写入值的Foo<in Nothing> 。 如果一个泛型类型有多个类型参数,每个类型参数可以独立地进行投影。 例如,如果类型被声明为接口Function<in T, out U>我们可以想象下面的星型投影:

Function<*, String>表示Function<in Nothing, String> ; Function<Int, *>表示Function<Int, out Any?> ; Function<*, *>表示Function<in Nothing, out Any?> 。 注意:星形投影非常类似Java的原始类型,但安全。