Могу ли я использовать лямбда-выражение для замены создания экземпляра абстрактного класса только одним абстрактным методом? - PullRequest
0 голосов
/ 28 мая 2018

(Этот вопрос задается в контексте Android, но отвечает только со знанием Kotlin.)

(Кроме того, я нашел некоторые ответы в SO на тот же вопрос в Java8 Lambda, но не могу найти одинотносительно Kotlin.)

Как и многие другие - сейчас я использую RxJava с Retrofit для сетевых вызовов.
И недавно я перешел на использование Kotlin.

IЯ объявил мой собственный 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, вышеупомянутое использование действительно кажется мне неуклюжим.
Чего я ожидаю от использования лямбдыкак показано ниже:

    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 голосов
/ 28 мая 2018

Вы можете сделать свой класс неабстрактным и добавить lamdba для наблюдения onNext событий в качестве последнего параметра ваших конструкторов:

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 позволяет поместить реализацию лямбды вне скобокв случае, если это последний аргумент в вашем методе / конструкторе.Все, что вам нужно сделать, это вызвать переданную лямбду внутри переопределенного onNext метода.

В конце концов, он позволяет вам написать точно такой же код, который вы ожидаете:

APIResponseObserver<Boolean>(this) { t: Boolean ->
    if (context == null) return@APIResponseObserver 
    //Do something with the boolean
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...