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

时间:2016-06-10 06:58:42

标签: generics 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突出显示被覆盖的功能演员说&#34;此演员阵容永远不会成功&#34;。我尝试使用in Anyout Any*,但它并不起作用。当我尝试使用*时,我无法在最初定义它的类中使用getPresenter()方法。 Android Studio抱怨类型不匹配:需要Nothing?,找到BaseFragment。 在Java中,相同的代码可以完美地工作,我并不认为这将是Kotlin中的一个问题。实现这个的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

这里的“施法永远不会成功”警告不正确。警告的正确消息应该是“未经检查的强制转换”,因为此强制转换可能正确也可能不正确,但运行程序无法发现此消息。

跟踪器中有an issue,实际上几天前是fixed。该修复可能会使它成为Kotlin 1.0.3。

答案 1 :(得分:0)

使用BasePresenter<*,*>

来自docs

  

星突起

     

有时你想说你对这种类型一无所知   参数,但仍希望以安全的方式使用它。这里安全的方式是   定义这种通用类型的投影,即每个具体的投影   该泛型类型的实例化将是该类型的子类型   投影。

     

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

     

对于Foo<out T>,其中T是协变类型参数   上限TUpperFoo<*>相当于Foo<out TUpper>。它   意味着当T未知时,您可以安全地读取值   来自TUpper的{​​{1}}。对于Foo<*>,其中Foo<in T>是逆变量   类型参数T相当于Foo<*>。它的意思是   当Foo<in Nothing>出现时,您无法以安全的方式写入Foo<*>   未知。对于T,其中Foo<T>是一个不变的类型参数   上限TTUpper相当于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<*, *>。注意:星形投影是   非常像Java的原始类型,但是很安全。