在 Kotlin 中隐藏基础 class 构造函数参数

Hiding base class constructor parameters in Kotlin

我想了解如何在 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 */
    }
    ...
}

我想我理解了问题:

During construction of a new instance of a derived class, the base class initialization is done as the first step (preceded only by evaluation of the arguments for the base class constructor) and thus happens before the initialization logic of the derived class is run.

我正在尝试为 Volley 解决这个问题,我需要将我的自定义请求作为请求,以便它可以传递到 RequestQueue。 RequestQueue 采用某种接口会更容易,但因为它不需要子类化。我可以通过其他方法向调用者隐藏这些复杂性,但我在 Kotlin 中其他时候也遇到过这个限制,我不确定如何解决它。

我对 volley 不熟悉,但我试着举了一个例子来让您了解如何解决您的问题。你可以做的是使用 companion object:

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 */
        }
    }
    ...
}

另一种方法是使用 decorator,使用该装饰器创建您的请求,然后将调用委托给它:

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)
    }
    ...
}