2017-09-17 69 views
2

我有一個抽象類用於監聽api回調如下。 ApiRs是一個父對象,每個API響應對象從它通配Kotlin通配符爲參數

abstract class ApiCallback<in T : ApiRs> { 

    open fun onSucceed(apiRsModel: T) {} 

    open fun onFailed(code: Int, 
         message: String) { 
    } 
} 

繼承,我也寫的函數請求API之前檢查網絡狀態,如果網絡沒有連接,那麼它會觸發onFailed

fun isNetworkAvailable(apiCallback: ApiCallback<ApiRs>?, 
          context: Context): Boolean{ 
     val connectivityManager = context 
       .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 
     val networkInfo = connectivityManager.activeNetworkInfo 

     // device network unreachable 
     if (networkInfo == null 
       || !networkInfo.isConnected) { 
      // callback with network error 
      apiCallback?.onFailed(code, message) 
      return false 
     } 

     return true 
    } 

參數類型ApiCallback<ApiRs>?實際上我想寫它像ApiCallback<? extends ApiRs>?,但Kotlin沒有通配符。如果我更換通用的ApiCallback<out ApiRs>?,它會顯示一個錯誤

投影用的ApiCallback

相應類型參數的變化相互矛盾有什麼辦法解決?或者只是我有錯誤的Kotlin通用概念?


2017年9月18日更新 - 正確的方法是:

方法:

fun <T : ApiRs> isNetworkAvailable(apiCallback: ApiCallback<T>?, 
             context: Context): Boolean { 
     val connectivityManager = context 
       .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 
     val networkInfo = connectivityManager.activeNetworkInfo 

     // device network unreachable 
     if (networkInfo == null 
       || !networkInfo.isConnected) { 
      // callback with network error 
      callbackWithFailed(
        apiCallback, 
        ApiError.API_ERROR_CODE_0, 
        context.getString(R.string.api_error_code_0)) 
      return false 
     } 

     return true 
    } 
+0

'ApiCallback '這將採取任何類型的'ApiRs'。請參閱star-projections https://kotlinlang.org/docs/reference/generics.html#star-projections –

+0

不起作用,當我使用'ApiCallback '時,比上面的警告將顯示 – Ivan

+0

@NikolaDespotoski是對的。每個API擴展ApiRs都會被接受,但是如果沒有其他的API將只有ApiRs類提供的功能。 – creativecreatorormaybenot

回答

1

我知道你是想接受你的方法apiCallback: ApiCallback<ApiRs>?的方式,通用型ApiCallback可以是ApiRs本身或其任何亞型。 Kotlin不是通配符,而是upper bounds。您可以聲明這樣的功能:

fun <T: ApiRs> isNetworkAvailable(apiCallback: ApiCallback<T>?, 
         context: Context) 
+0

謝謝!你的解決方案非常有意義! – Ivan