Kotlingenerics方法和inheritance
在我的代码中,我想在抽象类中创建一个方法,该方法返回一些Observable。 然后这个抽象类的实现将返回某些(指定)types的Observable。 不幸的是,Android Studio会在实现方法()中返回一个错误“types不匹配”:
- 预计:可观察
- find:Observable
我的MockDrawerList.getList()
返回Observable
请关注execute()
和buildUseCaseObservable
抽象类
public abstract class UseCase(threadExecutor: ThreadExecutor, postExecutionThread: PostExecutionThread) { private val threadExecutor: ThreadExecutor private val postExecutionThread: PostExecutionThread private var subscription: Subscription = Subscriptions.empty() init { this.postExecutionThread = postExecutionThread this.threadExecutor = threadExecutor } protected abstract fun buildUseCaseObservable(): Observable public fun execute(useCaseSubsriber: Subscriber) { subscription = buildUseCaseObservable() .subscribeOn(Schedulers.from(threadExecutor)) .observeOn(postExecutionThread.getScheduler()) .subscribe(useCaseSubsriber) } public fun unsubsribe() { if (!subscription.isUnsubscribed()) subscription.unsubscribe() } }
履行
Inject class GetDrawerListUseCase(threadExecutor: ThreadExecutor, postExecutionThread:PostExecutionThread) : UseCase(threadExecutor, postExecutionThread) { override fun buildUseCaseObservable(): Observable { return MockDrawerList.getList() } }
尽管String
是Any
一个子types,但Observable
Observable
在Kotlin中不被视为Observable
的子types。 你应该使用use-sitevariables :将buildUseCaseObservable
的返回types改为Observable
或Observable<*>
(后者相当于Observable
),代码应该被编译。
为什么通用types的inheritance不能基于types参数自动工作? 这是Joshua Bloch在Effective Java中最好解释的问题,项目28:使用有界通配符来提高API的灵活性。 简而言之,只有当types被保证不消耗其types参数的实例时,也就是说,如果具有通用参数T
的类没有以T
作为参数的方法,这才可以工作。 在Kotlin中可以强制执行的一种方法是声明站点差异 ,例如集合接口( kotlin.Collection
, kotlin.List
,…)。
然而, Observable
当然不是一个Kotlin类,所以编译器无法知道Observable
可以在需要Observable
地方安全地使用。 所以我们必须手动告诉编译器,我们可以只使用Observable
一个子集,而不要把T
作为参数,所以我们会得到好的inheritance。 这种“子集types”被称为Kotlin中的types投影 ,这种技术被称为使用地点方差。
您可以在官方语言文档“ generics”一节中阅读有关Kotlin中声明和使用站点差异的更多信息。