【问题标题】:Can I use lambda expression to replace instantiating an abstract class with only one abstract method?我可以使用 lambda 表达式来替换只用一个抽象方法实例化一个抽象类吗?
【发布时间】:2018-05-28 09:26:15
【问题描述】:

(这个问题是在 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) {

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

【问题讨论】:

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


    【解决方案1】:

    你可以让你的类非抽象并添加 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
    }
    

    【讨论】:

    • 特别感谢您的链接解释了它为什么起作用(作为最后一个参数)。谢谢!
    猜你喜欢
    • 2020-11-21
    • 1970-01-01
    • 2021-08-02
    • 2011-06-02
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多