我有以下工作Java代码但是当我将其转换为Kotlin时,代码无法编译
Java 代码
public interface Presenter<V> {
void attachView(V view);
}
实现上述接口的抽象类
public abstract class BasePresenter<T> implements Presenter<T> {
@Override
public void attachView(T view) {
this.view = view;
}
}
抽象类,它接受一个实现
上面接口的Type参数public abstract class PresenterActivity<P extends Presenter> extends BaseActivity {
protected P presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (presenter != null) {
presenter.attachView(this);
}
}
}
扩展BasePresenter的类
public class FooPresenter extends BasePresenter<BarView> {
...
}
扩展PresenterActivity的类
public class SomeActivity extends PresenterActivity<FooPresenter> implements BarView {
....
}
从上面的Java代码
转换的Kotlin 代码interface Presenter<in V> {
fun attachView(view: V)
}
实现上述接口的抽象类
abstract class BasePresenter<V> : Presenter<V> {
override fun attachView(view: V) {
this.view = view
}
}
使用Type参数实现上面的接口的抽象类,我不确定下面的<P : Presenter<Any>>
是否是正确的表达式
abstract class PresenterActivity<P : Presenter<Any>> : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (presenter != null) {
presenter!!.attachView(this)
}
}
}
扩展BasePresenter的类
class FooPresenter : BasePresenter<BarView>() {
....
}
扩展PresenterActivity的类
class SomeActivity : PresenterActivity<FooPresenter>(), BarView {
....
}
Kotlin类PresenterActivity
给出以下编译错误
错误:(9,44)类型参数不在其范围内:应该是'Presenter<Any>
'的子类型
这意味着FooPresenter
未被归类为Presenter<Any>
我假设Presenter<V>
是Presenter<Any>
的子类,我有一种感觉错了
答案 0 :(得分:3)
您的Java代码实际上存在类型安全问题:PresenterActivity<P extends Presenter>
使用raw type,当您稍后写presenter.attachView(this)
时,您不知道是否可以附加this
,但原始类型意味着编译器不会警告您。 Kotlin不会让你这样隐藏它。
我假设
Presenter<V>
是Presenter<Any>
的子类,我有一种感觉错了
in
实际上意味着Presenter<V>
是超级类型的Presenter<Any>
,而非子类型。请参阅https://kotlinlang.org/docs/reference/generics.html(或搜索协方差和逆变,有很多关于Stack Overflow的解释,否则,虽然Scala比Kotlin更多,但想法是相同的。)
我认为最简单的解决方案就像
// concrete subclasses must extend V
abstract class PresenterActivity<V, P : Presenter<V>> : BaseActivity() {
... presenter!!.attachView(this as V)
}
和
class SomeActivity : PresenterActivity<BarView, FooPresenter>(), BarView {
....
}