我试图了解如何在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中,其他时候我遇到了这一限制,我不确定如何解决。
答案 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)
}
...
}