首页 文章

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

提问于
浏览
3

我有一个抽象的泛型类:

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突出显示重写的函数,说明"This cast never succeed" . 我尝试使用 in Anyout Any* 但它不起作用 . 当我尝试使用 * 时,我无法在最初定义它的类中使用 getPresenter() 方法 . Android Studio抱怨类型不匹配:需要Nothing?,找到BaseFragment . 在Java中,相同的代码可以完美地工作,我不认为它会在Kotlin中出现问题 . 实现这个的正确方法是什么?

2 回答

  • 2

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

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

  • 0

    请使用 BasePresenter<*,*> .

    来自docs

    星形投影有时您想说您对类型参数一无所知,但仍希望以安全的方式使用它 . 这里安全的方法是定义泛型类型的这种投影,该泛型类型的每个具体实例都将是该投影的子类型 . 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>;函数<Int,>表示函数<Int,out Any?>;函数<,*>表示函数<in Nothing,out Any?> . 注意:星形投影非常类似于Java的原始类型,但是很安全 .

相关问题