实现参数化接口的类型中的Kotlin Pass

时间:2017-11-21 06:46:51

标签: java android types kotlin

我有以下工作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>的子类,我有一种感觉错了

1 个答案:

答案 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 {
    ....
}