2016-06-10 59 views
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突出顯示了重寫的函數,演員表示「此演員從未成功」。我嘗試使用in Any,out Any*,它不起作用。當我嘗試使用*時,我無法在最初定義的類中使用getPresenter()方法。 Android Studio抱怨類型不匹配:required without ?,找到BaseFragment。 在Java中,相同的代碼可以很好地工作,我不認爲這是Kotlin的問題。什麼是正確的方式來實現這一點?

回答

0

爲此使用BasePresenter<*,*>

docs

星預測

有時你想說,你一無所知的 類型參數,但還是要以安全的方式來使用它。這裏的安全方法是 來定義這種通用類型的投影,那個通用類型的每個具體實例都將是該投影的子類型。

科特林提供所謂的星形投影語法此:

對於Foo<out T>,其中T與 上限TUpper一個協變型參數,Foo<*>相當於Foo<out TUpper>。它 表示當T未知時,可以安全地從Foo<*>讀取 TUpper的值。對於Foo<in T>,其中T是逆變型 型參數,Foo<*>等效於Foo<in Nothing>。這意味着 沒有任何東西可以用Foo<*>以安全的方式寫入,當時T是 未知。爲Foo<T>,其中T是 上限TUpperFoo<*>不變類型參數是相當於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的原始類型,但是安全。

+0

我在我的問題中描述過。使用星型投影,我無法爲'getPresenter()。view'或者'getPresenter()。router')賦值。 Android Studio抱怨類型不匹配。 –

+0

我懷疑你所描述的是一個編譯器錯誤。我建議用一個例子報告問題。作爲解決方法,您可以投射由'getPresenter()':'(getPresenter()as BasePresenter ).view = something'返回的'BasePresenter <*, *>'。 – mfulton26

2

「鑄造不能成功」的警告在這裏是不正確的。警告的正確信息應該是「未經檢查的強制轉換」,因爲此轉換可能正確也可能不正確,但通過運行程序無法發現。

在跟蹤器中有an issue,實際上前幾天是fixed。該修補程序可能會使其成爲Kotlin 1.0.3。