15

在 Kotlin 中,当一个类有多个构造函数时,我们如何从另一个构造函数中调用指定的(来自 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)构造函数内的代码之前调用(再次抱歉:)。

这可以在 Kotlin 中解决吗?就像是

constructor(context: Context, text: String) {
    this.text = text
    this(context) 
}

编辑

只是为了澄清这个想法,因为它被问到了,这个想法是在一个活动中写这样的东西:

onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    verticalLayout {
        loadingButton("Some text")
        //or
        loadingButton() { this.text = "Some text"}
}

这显然不是很有用,但你明白了。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)
4

1 回答 1

24

对构造函数进行后调用的代码不能在 JVM 上存在,因为您必须在对类本身进行任何操作super(...) 之前调用。把它想象成超类包含一个私有字段,你必须先初始化它才能使用它。

这通常不是问题,因为您可以反过来调用构造函数:

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

术语如下:指定 - 主要,便利 - 次要

有关更多详细信息,请参阅类和继承 - Kotlin 编程语言

于 2016-03-14T18:27:22.543 回答