代码之家  ›  专栏  ›  技术社区  ›  Sira Lam

是否可以使用lambda表达式将实例化抽象类的实例替换为仅一个抽象方法?

  •  2
  • Sira Lam  · 技术社区  · 6 年前

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

    (同样,我在so中找到了一些关于java8 lambda中相同问题的答案,但是我找不到关于kotlin的答案。)

    像很多人一样-我现在正在使用 RxJava 具有 Retrofit 进行网络呼叫。
    最近我开始使用柯特林。

    我已经声明了我自己的 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 回复  |  直到 6 年前
        1
  •  4
  •   hluhovskyi    6 年前

    你可以使你的课程非抽象化,并添加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实现放在括号之外,以防它是方法/构造函数中的最后一个参数。您所需要做的就是在重写的内部调用传递的lambda 小精灵 方法。

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

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