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

标签 android lambda kotlin abstract-class rx-java2

(这个问题是在 Android 环境下提出的,但只能用 Kotlin 知识来回答。)

(另外,我在 SO 中找到了一些关于 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) { .

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

最佳答案

您可以使类成为非抽象类并添加 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
}

关于android - 我可以使用 lambda 表达式来替换仅用一个抽象方法实例化抽象类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50563094/

相关文章:

android - 背景附件:固定不能在 android/mobile 上工作

java - 无法使用 findViewById 找到 mpandroidchart

android - 在 Mac for Android 上交叉编译 "Hello World"

java - SharedPreferences逻辑错误

android - 可在多个 MPP 中重用的 Kotlin 公共(public)库

kotlin - 无法在 kotlin 中将 AsyncTask 转换为 Retrofit2

c# - Lambda,从嵌套列表中获取属性

templates - 通过函数指针函数将lambda作为模板参数传递给模板

python - tkinter:将事件参数和附加参数传递给事件处理函数

android - RecyclerView SnapHelper - 如何更改已捕捉和未捕捉项目的背景?