gpt4 book ai didi

android - Kotlin 泛型属性问题

转载 作者:行者123 更新时间:2023-11-29 19:06:21 25 4
gpt4 key购买 nike

在将我的 android 项目从 java 转换为 Kotlin 时,我遇到了一些 Kotlin 问题。假设我有接口(interface) I 和扩展接口(interface) I 的接口(interface) O。

interface I{

}

interface O: I{

}

泛型类 A 具有扩展接口(interface) I 的泛型参数 V,以及扩展类 A 的泛型类 B:

abstract class A<V: I> {

}

class B : A<O>() {

}

当我尝试创建这样的属性时:

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

我收到编译器错误“需要 A,找到 B”。在 Java 中,这将毫无问题地工作。我如何使用 Kotlin 访问它?

我需要在我的应用程序中对 Basic 类使用这种方法。

具有 Navigator 类通用参数的 BaseViewModel:

abstract class BaseViewModel<N>(application: Application, val repositoryProvider:
RepositoryProvider) : AndroidViewModel(application) {

var navigator: N? = null

fun onDestroyView() {
navigator = null
}

open fun onViewAttached() {

}
}

基础 Activity 类:

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

// .......
}

BaseNavigator 接口(interface)用于 VM - 查看通信:

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?)
}

这里是我扩展这些类的示例代码:

AuthViewModel:

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

// ....

}

授权导航器:

interface AuthNavigator : BaseNavigator {
fun requestGoogleAuth(code: Int)

fun requestFacebookAuth(callback: FacebookCallback<LoginResult>)
}

以及出现错误的 AuthActivity 类:

class AuthActivity : BaseActivity<ActivityAuthBinding, BaseViewModel<BaseNavagator>>(),
GoogleApiClient.OnConnectionFailedListener, AuthNavigator {

@Inject
lateinit var mViewModel: AuthViewModel

override val viewModel: BaseViewModel<BaseNavigator>
get() = mViewModel // Required:BaseViewModel<BaseNavigator> Found: AuthViewModel

我还尝试将 AuthActivity 中的通用参数从 BaseViewModel 更改为 AuthViewModel,但编译器抛出错误“需要 BaseViewModel”。

And i tried to change

override val viewModel: BaseViewModel<BaseNavigator>
get() = mViewModel

to

override val viewModel: AuthViewModel
get() = mViewModel

但在这种情况下,编译器会抛出错误“Property type is 'AuthViewModel', which is not a subtype type of overridden”。

更新:当我向 BaseViewModel 添加属性时,这有效:

BaseViewModel<out N : BaseNavigator>

但在这种情况下我只能创建

private var navigator: N? = null

我需要将其公开,以便我可以在 Activity 类中设置它。我可以为此属性创建公共(public) setter 吗?当我尝试创建 setter 时发生错误:

private var navigator: N? = null

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

最佳答案

看起来您希望类型参数的行为协变。 Kotlin 使用声明站点变量。如果您不指定方差,则泛型类型参数不变

换句话说,现在 A<I> 之间没有关系和 A<O> .但是如果你声明

abstract class A<out V : I>

然后 A<O>A<I> 的子类型.

(还有 <in> 用于逆变,它以相反的方式工作。有关更多详细信息,请参阅 https://kotlinlang.org/docs/reference/generics.html。)

关于android - Kotlin 泛型属性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47085763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com