我正在使用 MVP 架构实现一个简单的应用。
这是我的 MvpView
和 MvpPresenter
界面(MvpModel
没有什么有趣的地方,所以我跳过了它):
/// MvpView.java
public interface MvpView {
}
/// MvpPresenter.java
public interface MvpPresenter<V extends MvpView> {
void attachView(V view);
void detachView();
}
现在我有了一个基本的 MvpView
实现,它是一个 Activity
:
// BaseActivity.java
public abstract class BaseActivity<V extends MvpView, P extends MvpPresenter<V>>
extends AppCompatActivity implements MvpView {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPresenter().attachView(this);
}
public abstract P getPresenter();
// other logic
}
对我来说一切看起来都是正确的,但是行中有一个编译错误:
getPresenter().attachView(this);
如果我将强制转换添加到 V
然后项目编译并且一切正常:
getPresenter().attachView((V) this);
1。问题是为什么我需要这个转换或者为什么我在没有转换的情况下遇到这个不兼容的类型错误?
(1 已由 Eran 回答)
2。在此示例中,我如何将 V
链接到 BaseActivity
或如何更好地实现此 MVP 方法?
这对我来说很奇怪,因为我的 BaseActivity
正在扩展 MvpView
,因为它是由这个通用参数定义的:V extends MvpView
!
最佳答案
getPresenter()
是 P
类型的实例, 它扩展了 MvpPresenter<V>
.因此getPresenter.attachView()
期望类型为 V
的参数.
现在,我们知道 V
必须实现 MvpView
,我们也知道 BaseActivity
工具 MvpView
,但此实现不一定匹配。
例如,您可以创建一个具体的子类 SubBaseActivity
并实例化它:
SubBaseActivity<MvpViewImpl, MvpPresenterImpl<MvpViewImpl>>
activity = new SubBaseActivity<> (); // let's ignore the fact that you are not suppose
// to instantiate Android activities this way
现在getPresenter()
返回 MvpPresenterImpl
和 getPresenter().attachView()
期望类型为 MvpViewImpl
的参数.但是this
是不类型MvpViewImpl
.
当您从 BaseActivity<V,P>
进行不安全转换时至 V
,你是在告诉编译器 BaseActivity<V,P>
可以转换为 V
.然而,这在运行时起作用的原因是编译器删除泛型类型参数 V
和 P
.由于 V
的类型绑定(bind)是MvpView
, 类型转换到 V
成为 MvpView
的铸件,这BaseActivity
实现。
关于java - 了解泛型 : Incompatible types when class has generic type and implements one of its parametrised superclass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45056005/