实现泛型类型接口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现泛型类型接口相关的知识,希望对你有一定的参考价值。

假设我有以下接口:

public interface MvpView { }

public interface MvpPresenter<V extends MvpView> {
    void attach(V view);
}

然后是一个实现MvpPresenter的基类

public class BasePresenter<V extends MvpView> implements MvpPresenter<V> {
    private V view;

    @Override
    public void attach(V view) {
        this.view = view;
    }
}

最后是扩展BasePresenter的以下类

public abstract class BaseFragment<P extends MvpPresenter> implements MvpView {
    P presenter;

    public void someMethod() {
        presenter.attach(this);
    }
}

虽然这编译它并不安全,因为无法保证类的实现将实现正确的MvpViewP presenter使用的那个)。为了安全起见,我遗漏了someMethod的代码,每个实现都必须填写完全相同的代码presenter.attach(this)

我想做什么,但我不知道如何如下:

public abstract class BaseFragment<V extends MvpView, P extends MvpPresenter<V>> implements V {
    P presenter;

    public void someMethod() {
        presenter.attach(this);
    }
}

有没有办法实现这个目标?

答案

像这样宣布BaseFragment

abstract class BaseFragment<P extends MvpPresenter<R>, R extends BaseFragment<P,R>> implements MvpView {
    P presenter;

   public void someMethod() {
        presenter.attach(getThis());
   }

   abstract R getThis();
   }
}

并使用这样的扩展,

class MyFragment extends BaseFragment<MvpPresenter<MyFragment>, MyFragment> {

    @Override
    MyFragment getThis() {
        return this;
    }   

}
另一答案

这编译:

public abstract class BaseFragment<P extends MvpPresenter<BaseFragment>> implements MvpView {

    P presenter;

    public void someMethod() {
        presenter.attach(this);
    }
}

但我还没有找到一种实际的子类化方法。我不确定MvpView是否真的需要任何东西。也许这样的事情会有用:

public interface MvpPresenter<V> {

    void attach(V view);
}

public class BasePresenter<V> implements MvpPresenter<V> {
    private V view;

    @Override
    public void attach(V view) {
        this.view = view;
    }
}

public abstract class BaseFragment<R extends BaseFragment>  {

    MvpPresenter<R> presenter;

    public void someMethod() {
        presenter.attach(getThis());
    }

    abstract R getThis();
}

public class MyBaseFragment extends BaseFragment<MyBaseFragment> {

    @Override
    MyBaseFragment getThis() {
        return this;
    }

}
另一答案

根据boobalan gnanasekaran和user158037的答案,我这样做了:

public interface MvpView { }

public interface MvpPresenter<V extends MvpView> {
    void attach(V view);
}

public class BasePresenter<V extends MvpView> implements MvpPresenter<V> {
    private V view;

    @Override
    public void attach(V view) {
        this.view = view;
    }

    public V getView() {
        return view;
    }
}

public abstract class BaseFragment<V extends MvpView, P extends MvpPresenter<V>> {
    P presenter;

    protected abstract V getThis();

    public void someMethod() {
        presenter.attach(getThis());
    }

    public P getPresenter() { return presenter; }
}

并举例说明

public interface MoviesContract {
    interface Presenter extends MvpPresenter<MoviesContract.View> {
        void loadMovies();
    }

    interface View extends MvpView {
        void onMoviesLoaded();
    }
}

public class MoviesPresenter extends BasePresenter<MoviesContract.View>
    implements MoviesContract.Presenter {

    @Override
    public void loadMovies() {
        getView.onMoviesLoaded();
    }
}


public class MoviesFragment extends BaseFragment<MoviesContract.View, MoviesContract.Presenter>
    implements MoviesContract.View {

    @Override
    public MoviesContract.View getThis() {
        return this;
    }

    public loadMovies() {
        getPresenter().loadMovies();
    }

    @Override
    public void onMoviesLoaded() {
        //
    }
}

以上是关于实现泛型类型接口的主要内容,如果未能解决你的问题,请参考以下文章

泛型详解

定义泛型接口

当两个类型参数在C#中实现公共接口时,如何将泛型强制转换为它实现的接口

如何确定一个类型是不是实现了特定的泛型接口类型

实现泛型类型接口

泛型类型参数协方差和多接口实现