【问题标题】:Kotlin generic inheritanceKotlin 泛型继承
【发布时间】:2017-10-28 01:50:56
【问题描述】:

我有一个问题,无法解决。我有一个接口Presenter,它是通用的,可以采用接口MvpView的任何子类型

interface Presenter<in V : MvpView> {
    fun attachView(view: V)
    fun detachView()
}

那我还有一个 抽象类BasePresenter 是Presenter 的子类型

abstract class BasePresenter<V : MvpView> : Presenter<V> {

    protected var mvpView: V? = null
        protected get

    override fun attachView(view: V) {
        this.mvpView = view
    }

    override fun detachView() {
        mvpView = null
    }
}

我有一堂课

abstract class BaseMvpActivity<P : BasePresenter<T>, T : MvpView> : BaseActivity(), MvpView {

    @Inject lateinit protected var presenter: P

    protected abstract fun inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        inject()
        initPresenter(savedInstanceState)
    }

    protected fun initPresenter(savedInstanceState: Bundle?) {
        presenter.attachView(this)
    }

    override fun onDestroy() {
        presenter.detachView()
        super.onDestroy()
    }
}

尝试调用presenter.attachView(this)时出现错误

Type mismatch: inferred type is BaseMvpActivity<P, T> but T was expected

我也尝试这样做abstract class BaseMvpActivity&lt;P : BasePresenter&lt;*&gt;&gt; : BaseActivity(),但也有类似Type mismatch: inferred type is BaseMvpActivity&lt;P&gt; but Nothing was expected的错误

我该如何解决这个问题?谢谢。

【问题讨论】:

  • attachView() 需要一个 T 作为参数。你正在传递this。 this 不是泛型类型 T。它甚至不是 T 应该实现的 MvpView。
  • 看,我应该将MvpView 的任何子类型传递给这个方法。我的BaseMvpActivity 实现了这个接口。那怎么了?
  • 看,不,直到您在 26 秒前进行编辑,它才实现此接口。但即便如此。 List 只接受 T。您不能将 Int 或 Double 添加到此类列表中,即使 Int 和 Double 扩展 Number,因为 Int 和 Double 与 T 类型不同。
  • 我的BaseActivity 实现了MvpView。我刚刚进行了编辑以使其更加明显。是的,您对列表类比是正确的。那么如何让这段代码可编译呢?
  • abstract class BaseMvpActivity&lt;P : BasePresenter&lt;BaseMvpActivity&lt;P&gt;&gt;&gt; 会编译。

标签: generics inheritance kotlin type-mismatch


【解决方案1】:

您为什么要使BasePresetner 泛型,因为您不会返回该泛型类型的值。我们使用泛型来防止从方法返回值的类型转换,并防止可能的 Cast 异常。

我想说的是,您不需要使 BasePresenter 通用。只需将 mvpView 声明为 MvpView 并使用它的方法。假设如果您确实将其设为通用,那么您将无法获得任何加分,因为您仍然只能访问 MvpView 的方法(不是sub-class)。

abstract class BasePresenter : Presenter<V> {

    protected var mvpView: MvpView = null
        protected get

    override fun attachView(view: MvpView) {
        this.mvpView = view
    }

    override fun detachView() {
        mvpView = null
    }
}

希望对你有帮助。

【讨论】:

  • Java 代码只编译(带有警告),因为您使用的是原始类型而不是正确键入游览变量。将MvpViewSubClass class1 = new MvpViewSubClass&lt;P&gt;(); 替换为MvpViewSubClass&lt;P&gt; class1 = new MvpViewSubClass&lt;&gt;();,它也不会像预期的那样编译。
  • 哦..我的错..让我弄清楚
  • @JBNizet 我已更改答案,请检查并告诉我,您对此有何看法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
相关资源
最近更新 更多