Kotlin泛型:Kotlin不承认我的类具有正确的继承

这是我的简单例子:

interface IMyView interface IMyViewModel<VIEW : IMyView, in ITEM> { fun attachView(view: VIEW) fun getView(): VIEW? } class myView : IMyView class MyViewModel : IMyViewModel<myView, String> { override fun attachView(view: myView) { TODO("not implemented") } override fun getView(): myView? { TODO("not implemented") } } abstract class MyBaseClass<VIEWMODEL : IMyViewModel<out IMyView, *>> : IMyView { protected lateinit var viewModel: VIEWMODEL fun myInvocation(): Unit { viewModel.attachView(this as IMyView) } } class MyMainClass : MyBaseClass<MyViewModel>() 

问题是最后一行,因为MyViewModel不被识别为IMyViewModel。 错误信息如下:

 Type argument is not within its bounds. Expected: IMyViewModel<IMyView, *> Found: MyViewModel 

在Java中,它的作品。 我必须适应什么才能使它在Kotlin中也可行?

******更新******

如果你使用

 abstract class MyBaseClass<VIEWMODEL : IMyViewModel<out IMyView, *>> 

(请参阅上面更新的Kotlin代码)

那么我不能调用myInvocation因为那个调用我需要在IMyView中。 所以这是一场灾难。 我所做的一切都会导致其他问题。 在Java中这很容易。

您的代码的问题是,当您创建一个上限VIEWMODEL : IMyViewModel<IMyView, *> ,类型可以满足此绑定只有实现IMyViewModelVIEW类型参数完全替换IMyView ,不允许IMyView子类型因此MyViewModel被拒绝)。 换句话说, VIEW是不变的 。

由于Kotlin允许您在声明站点和使用站点指定类型参数差异,因此可以通过执行以下操作之一来解决此问题:

  • 使用声明站点差异使IMyViewModelVIEW类型参数协变:

     interface IMyViewModel<out VIEW : IMyView, in ITEM> ^^^ 
  • VIEWMODEL上限的IMyViewModel的使用位置添加一个out IMyViewModel

     abstract class MyBaseClass<VIEWMODEL : IMyViewModel<out IMyView, *>> ^^^ 
  • 将另一个类型参数T添加到MyBaseClass ,并在IMyViewModel<T, *>使用它:

     abstract class MyBaseClass<T : IMyView, VIEWMODEL : IMyViewModel<T, *>> class MyMainClass: MyBaseClass<myView, MyViewModel>() 

我现在解决了这个问题。 我犯了一个概念错误。 这是解决方案:

 interface IMyViewModel<VIEW : IMyView, in ITEM> { fun attachView(view: VIEW) fun getView(): VIEW? } class MyViewModel : IMyViewModel<IMyView, String> { override fun attachView(view: IMyView) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getView(): IMyView? { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } } abstract class MyBaseClass<VIEWMODEL : IMyViewModel<IMyView, *>> : IMyView { protected lateinit var viewModel: VIEWMODEL fun myInvocation(): Unit { viewModel.attachView(this) } } class MyMainClass : MyBaseClass<MyViewModel>()