Problema de properties genéricas de Kotlin

Tengo algunos problemas con Kotlin al traducir mi proyecto de Android de Java a Kotlin. Digamos que tengo la interfaz I y la interfaz O que extiende la interfaz I.

interface I{ } interface O: I{ } 

Y la class genérica A que tiene el parámetro genérico V que extiende la interfaz I, y la class genérica B que extiende la class A:

 abstract class A<V: I> { } class B : A<O>() { } 

Cuando bash crear dicha propiedad:

 val returnB: A<I> get() = b 

Estoy obteniendo el error de compilation 'requerido A, encontrado B'. En Java esto funcionará sin problemas. ¿Cómo puedo acceder a esto usando Kotlin?

Necesito usar este enfoque para las classs Básicas en mi aplicación.

BaseViewModel que tiene un parámetro genérico para la class Navigator:

 abstract class BaseViewModel<N>(application: Application, val repositoryProvider: RepositoryProvider) : AndroidViewModel(application) { var navigator: N? = null fun onDestroyView() { navigator = null } open fun onViewAttached() { } } 

Clase BaseActivity:

 abstract class BaseActivity<T : ViewDataBinding, V : BaseViewModel<BaseNavigator>> : AppCompatActivity(), BaseFragment.Callback, BaseNavigator { // ....... private var mViewModel: V? = null /** * Override for set view model * @return view model instance */ abstract val viewModel: V // ....... } 

La interfaz de BaseNavigator utiliza para VM – Ver comunicación:

 interface BaseNavigator { fun invokeIntent(intent: Intent?, b: Bundle?, c: Class<*>?, forResult: Boolean, requestCode: Int) fun replaceFragment(fragment: Fragment, addToBackStack: Boolean) fun showDialogFragment(fragment: DialogFragment?, tag: String?) fun showToast(message: String?) } 

Aquí código de ejemplo donde estoy ampliando estas classs:

AuthViewModel:

 class AuthViewModel(context: Application, repositoryProvider: RepositoryProvider) : BaseViewModel<AuthNavigator>(context,repositoryProvider) { // .... } 

AuthNavigator:

 interface AuthNavigator : BaseNavigator { fun requestGoogleAuth(code: Int) fun requestFacebookAuth(callback: FacebookCallback<LoginResult>) } 

Y la class AuthActivity donde apareció el error:

 class AuthActivity : BaseActivity<ActivityAuthBinding, BaseViewModel<BaseNavagator>>(), GoogleApiClient.OnConnectionFailedListener, AuthNavigator { @Inject lateinit var mViewModel: AuthViewModel override val viewModel: BaseViewModel<BaseNavigator> get() = mViewModel // Requinetworking:BaseViewModel<BaseNavigator> Found: AuthViewModel 

}

También intenté cambiar el parámetro genérico en AuthActivity de BaseViewModel a AuthViewModel, pero el comstackdor arroja el error 'BaseViewModel' requerido.

 And i tried to change override val viewModel: BaseViewModel<BaseNavigator> get() = mViewModel to override val viewModel: AuthViewModel get() = mViewModel 

pero en este caso el comstackdor arroja el error 'El tipo de propiedad es' AuthViewModel ', que no es un tipo de subtipo anulado'.

Actualización: Eso funciona cuando agrego una propiedad a BaseViewModel:

 BaseViewModel<out N : BaseNavigator> 

Pero en este caso solo puedo crear

 private var navigator: N? = null 

que necesito ser público para poder configurarlo en la class de Actividad. ¿Puedo crear public setter para esta propiedad? Cuando bash crear setter, ocurre un error:

 private var navigator: N? = null fun setNavigator(n: N) { // error: Type parameter N is declanetworking as 'out' but occurs in 'in' position in type N navigator = n } 

    Parece que está esperando que el parámetro de tipo se comporte de forma coherente . Kotlin usa la varianza del sitio de statement. Si no especifica la varianza, los parameters de tipo genérico son invariables .

    En otras palabras, en este momento no hay relación entre A<I> y A<O> . Pero si declaras

     abstract class A<out V : I> 

    entonces A<O> es un subtipo de A<I> .

    (También existe <in> para la contravariancia, que funciona al revés. Consulte https://kotlinlang.org/docs/reference/generics.html para get más detalles).