我可以使用lambda表达式替换仅使用一个抽象方法实例化抽象类吗?

时间:2018-05-28 09:26:15

标签: android lambda kotlin abstract-class rx-java2

(这个问题是在Android背景下提出的,但只有Kotlin知识才能回答。)

(另外,我在Java8 Lambda中找到了关于相同问题的一些答案,但我找不到关于Kotlin的答案。)

与许多人一样 - 我现在使用RxJavaRetrofit进行网络通话 最近我转而使用Kotlin。

我已声明自己的Observer以集中处理错误。

这是我的APIResponseObserver<T> extends Observer<T> :(简化)

abstract class APIResponseObserver<T> : Observer<T> {

    constructor(fragment: BaseFragment) : super(fragment)

    constructor(activity: BaseActivity) : super(activity)

    override fun onSubscribe(d: Disposable) {
        fragment?.addToCompositeDisposable(d)
        activity?.addToCompositeDisposable(d)
    }

    override fun onError(e: Throwable) {
        val fm = if (activity == null) fragment?.childFragmentManager else activity?.supportFragmentManager
        if (e is APIManager.APIException && e.message != null) {
            fm?.showSimpleTextDialog(e.message!!)
        } else {
            val errorMsg = if (activity == null) fragment?.getString(R.string.network_error) else activity?.getString(R.string.network_error)
            errorMsg?.let {
                fm?.showSimpleTextDialog(it)
            }
        }
    }

    override fun onComplete() {
    }
}

如您所见,只有onNext()没有被覆盖。

这就是我现在使用它的方式:

    APIManager.getSomeBoolean().subscribe(object : APIResponseObserver<Boolean>(this) {
        override fun onNext(t: Boolean) {
            if (context == null) return
            //Do something with the boolean
        }
    })

使用一周的Kotlin后,上述用法对我来说确实很笨拙 我期望使用如下的lambda:

    APIManager.getSomeBoolean().subscribe(APIResponseObserver<Boolean>(this) {t: Boolean
        if (context == null) return
        //Do something with the boolean
    })

这样我就不需要写object :override fun onNext(t: Boolean) {

但是,这可能吗?如果是,我该如何实现?

1 个答案:

答案 0 :(得分:4)

您可以将类设为非抽象类,并添加lamdba以观察构造函数的onNext个事件as last parameter

class APIResponseObserver<T> : Observer<T> {

    private val onNextCallback: (T) -> Unit

    constructor(fragment: BaseFragment, onNext: (T) -> Unit) : super(fragment) {
       onNextCallback = onNext
    }

    constructor(activity: BaseActivity, onNext: (T) -> Unit) : super(activity) {
       onNextCallback = onNext
    }

    ... other methods ...

    override fun onNext(t: T) {
        onNextCallback.invoke(t)
    }
}

Kotlin允许将lambda实现放在括号外,以防它是你的方法/构造函数中的最后一个参数。您需要做的就是在重写的onNext方法中调用传递的lambda。

最后,它允许您编写与预期完全相同的代码:

APIResponseObserver<Boolean>(this) { t: Boolean ->
    if (context == null) return@APIResponseObserver 
    //Do something with the boolean
}