在将我的 android 项目从 java 转换为 Kotlin 时,我遇到了 Kotlin 的一些问题。假设我有接口 I 和扩展接口 I 的接口 O。
interface I{
}
interface O: I{
}
泛型类 A 具有扩展接口 I 的泛型参数 V,泛型类 B 扩展类 A:
abstract class A<V: I> {
}
class B : A<O>() {
}
当我试图创建这样的属性时:
val returnB: A<I>
get() = b
我收到编译器错误“需要 A,找到 B”。在 Java 中,这将毫无问题地工作。我如何使用 Kotlin 访问它?
我需要在我的应用程序中对 Basic 类使用这种方法。
BaseViewModel 具有 Navigator 类的通用参数:
abstract class BaseViewModel<N>(application: Application, val repositoryProvider:
RepositoryProvider) : AndroidViewModel(application) {
var navigator: N? = null
fun onDestroyView() {
navigator = null
}
open fun onViewAttached() {
}
}
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
// .......
}
BaseNavigator 接口用于 VM - View 通信:
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?)
}
这是我扩展这些类的示例代码:
授权视图模型:
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,但编译器会抛出错误“required BaseViewModel”。
And i tried to change
override val viewModel: BaseViewModel<BaseNavigator>
get() = mViewModel
to
override val viewModel: AuthViewModel
get() = mViewModel
但在这种情况下,编译器会抛出错误“属性类型是 'AuthViewModel',它不是被覆盖的子类型”。
更新: 当我将属性添加到 BaseViewModel 时有效:
BaseViewModel<out N : BaseNavigator>
但在这种情况下,我只能创建
private var navigator: N? = null
我需要公开,以便我可以在 Activity 类中设置它。我可以为此属性创建公共设置器吗?当我尝试创建 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
}