在Kotlin中隐藏基类构造函数参数

时间:2019-01-03 18:42:39

标签: kotlin android-volley

我试图了解如何在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解决此问题,在这里我需要将自定义请求作为Request,以便可以将其传递到RequestQueue。 RequestQueue接受某种类型的接口会更容易,但是由于它不需要子类化。我还可以通过其他方法向调用者隐藏这些复杂性,但是在Kotlin中,其他时候我遇到了这一限制,我不确定如何解决。

1 个答案:

答案 0 :(得分:3)

我对排球并不熟悉,但是我尝试提出一个示例,该示例应该使您对如何解决问题有一些了解。您可以使用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)
    }
    ...
}