Скрытие параметров конструктора базового класса в Котлине - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь понять, как скрыть параметр базового конструктора в подклассе в kotlin.Как вы кладете фасад поверх базового конструктора?Это не работает:

import com.android.volley.Request
import com.android.volley.Response

class MyCustomRequest(url: String)
      : Request<String>(Request.Method.POST, url, hiddenListener) {
    private fun hiddenListener() = Response.ErrorListener {
        /* super secret listener */
    }
    ...
}

Мне кажется, я понимаю проблему:

Во время создания нового экземпляра производного класса инициализация базового класса выполняется какпервый шаг (предшествует только оценке аргументов для конструктора базового класса) и, таким образом, происходит до запуска логики инициализации производного класса.

Я пытаюсь решить эту проблему для Volley,где мне нужно, чтобы мой пользовательский запрос был запросом, чтобы его можно было передать в RequestQueue.Было бы легче, если бы RequestQueue использовал какой-то интерфейс, но так как он не должен быть подклассом.Есть и другие способы, которыми я могу скрыть эти сложности от звонящего, но это ограничение встречалось для меня в другой раз в Котлине, и я не уверен, как его решить.

1 Ответ

0 голосов
/ 03 января 2019

Я не знаком с залпом, но я попытался найти пример, который должен дать вам некоторое представление о том, как решить вашу проблему. Что вы можете сделать, это использовать сопутствующий объект :

interface MyListener {
    fun handleEvent()
}

open class Base<T>(anything: Any, val listener: MyListener) { // this would be your Request class
    fun onSomeEvent() {
        listener.handleEvent()
    }
}

class Derived(anything: Any) : Base<Any>(anything, hiddenListener) { // this would be your MyCustomRequest class
    private companion object {
        private val hiddenListener  = object : MyListener {
            override fun handleEvent() {
                // do secret stuff here
            }
        }
    }
}

Итак, если вы примените это к своей проблеме, результат должен выглядеть примерно так:

class MyCustomRequest(url: String)
    : Request<String>(Request.Method.POST, url, hiddenListener) {
    private companion object {
        private val hiddenListener = Response.ErrorListener {
            /* super secret listener */
        }
    }
    ...
}

Другой способ - использовать декоратор , создать свой запрос с этим декоратором и просто делегировать ему вызовы:

class Decorator(anything: Any) {
    private var inner: Base<Any>
    private val hiddenListener: MyListener =  object : MyListener {
        override fun handleEvent() {  }
    }
    init {
        inner = Base(anything, hiddenListener)
    }
}

И еще раз для вашего примера, который будет выглядеть так:

class MyCustomRequest(url: String) {
    private var inner: Request<String>
    private val hiddenListener = Response.ErrorListener {
        /* super secret listener */
    }
    init {
        inner = Request<String>(Request.Method.POST, url, hiddenListener)
    }
    ...
}
...