从 Kotlin 中的另一个构造函数调用默认构造函数
Call a default constructor from another one in Kotlin
在 Kotlin 中,当一个 class 有多个构造函数时,我们如何调用 designated(来自 iOS 世界我找不到更好的名字) 来自另一个构造函数的构造函数。
举个例子
final class LoadingButton: LinearLayout {
var text:String? = null
constructor(context: Context, text: String) : this(context) {
this.text = text
}
constructor(context: Context) : super(context) {
val t = this.text
this.view {
button(t) { /* ... */}
}
}
}
在这里,如果我执行 loadingButton("TEST", {})
,该字符串不会传播到按钮,因为 this(context)
在 convenience 构造函数内部的代码之前被调用(再次抱歉:).
可以在 Kotlin 中解决这个问题吗?像
constructor(context: Context, text: String) {
this.text = text
this(context)
}
编辑
只是为了澄清这个想法,因为它被问到,我的想法是在 activity 中写这样的东西:
onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
loadingButton("Some text")
//or
loadingButton() { this.text = "Some text"}
}
这显然没有多大用处,但您明白了。文本 属性 可以在构造时或以后知道。
这尤其没用,因为 Kotlin 有参数的默认值,但我正在研究这门语言,运行 解决了这个问题。
编辑 2
另一个说明是我在布局中使用 Anko,因此 loadingButton
方法如下所示:
inline fun ViewManager.loadingButton() = loadingButton { }
inline fun ViewManager.loadingButton(init: LoadingButton.() -> Unit) = ankoView({ LoadingButton(it) }, init)
inline fun ViewManager.loadingButton(text: String, init: LoadingButton.() -> Unit) = ankoView({ LoadingButton(it, text) }, init)
JVM 上不能存在调用构造函数的 post 的代码,因为您必须在 之前调用 super(...)
您对 class 本身。把它想象成 super class 包含一个私有字段,你必须先初始化它才能使用它。
这通常不是问题,因为您可以反过来调用构造函数:
constructor(context: Context, text: String?) : super(context) {
this.text = text
this.view {
button(text) { /* ... */}
}
}
constructor(context: Context) : this(context, null)
constructor(context: Context, text: String) : this(context, text)
上面的代码与默认参数大致相同:
constructor(context: Context, text: String? = null) : super(context) {
this.text = text
this.view {
button(text) { /* ... */}
}
}
为了使此代码符合习惯(且简洁),请使用 主要 构造函数:
class LoadingButton(context: Context, val text: String? = null): LinearLayout(context) {
init {
this.view {
button(text) { /* ... */}
}
}
}
术语如下:指定 - 主要,方便 - 次要
有关详细信息,请参阅 Classes and Inheritance - Kotlin Programming Language。
在 Kotlin 中,当一个 class 有多个构造函数时,我们如何调用 designated(来自 iOS 世界我找不到更好的名字) 来自另一个构造函数的构造函数。
举个例子
final class LoadingButton: LinearLayout {
var text:String? = null
constructor(context: Context, text: String) : this(context) {
this.text = text
}
constructor(context: Context) : super(context) {
val t = this.text
this.view {
button(t) { /* ... */}
}
}
}
在这里,如果我执行 loadingButton("TEST", {})
,该字符串不会传播到按钮,因为 this(context)
在 convenience 构造函数内部的代码之前被调用(再次抱歉:).
可以在 Kotlin 中解决这个问题吗?像
constructor(context: Context, text: String) {
this.text = text
this(context)
}
编辑
只是为了澄清这个想法,因为它被问到,我的想法是在 activity 中写这样的东西:
onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
loadingButton("Some text")
//or
loadingButton() { this.text = "Some text"}
}
这显然没有多大用处,但您明白了。文本 属性 可以在构造时或以后知道。
这尤其没用,因为 Kotlin 有参数的默认值,但我正在研究这门语言,运行 解决了这个问题。
编辑 2
另一个说明是我在布局中使用 Anko,因此 loadingButton
方法如下所示:
inline fun ViewManager.loadingButton() = loadingButton { }
inline fun ViewManager.loadingButton(init: LoadingButton.() -> Unit) = ankoView({ LoadingButton(it) }, init)
inline fun ViewManager.loadingButton(text: String, init: LoadingButton.() -> Unit) = ankoView({ LoadingButton(it, text) }, init)
JVM 上不能存在调用构造函数的 post 的代码,因为您必须在 之前调用 super(...)
您对 class 本身。把它想象成 super class 包含一个私有字段,你必须先初始化它才能使用它。
这通常不是问题,因为您可以反过来调用构造函数:
constructor(context: Context, text: String?) : super(context) {
this.text = text
this.view {
button(text) { /* ... */}
}
}
constructor(context: Context) : this(context, null)
constructor(context: Context, text: String) : this(context, text)
上面的代码与默认参数大致相同:
constructor(context: Context, text: String? = null) : super(context) {
this.text = text
this.view {
button(text) { /* ... */}
}
}
为了使此代码符合习惯(且简洁),请使用 主要 构造函数:
class LoadingButton(context: Context, val text: String? = null): LinearLayout(context) {
init {
this.view {
button(text) { /* ... */}
}
}
}
术语如下:指定 - 主要,方便 - 次要
有关详细信息,请参阅 Classes and Inheritance - Kotlin Programming Language。