140

如何在 Kotlin 中声明辅助构造函数?

有没有这方面的文件?

以下不编译...

class C(a : Int) {
  // Secondary constructor
  this(s : String) : this(s.length) { ... }
}
4

13 回答 13

108

更新:由于 M11 (0.11.*) Kotlin 支持辅助构造函数


目前 Kotlin 仅支持主构造函数(以后可能会支持辅助构造函数)。

二级构造函数的大多数用例都通过以下技术之一解决:

技术1.(解决你的情况)在你的类旁边定义一个工厂方法

fun C(s: String) = C(s.length)
class C(a: Int) { ... }

用法:

val c1 = C(1) // constructor
val c2 = C("str") // factory method

技术 2.(也可能有用)定义参数的默认值

class C(name: String? = null) {...}

用法:

val c1 = C("foo") // parameter passed explicitly
val c2 = C() // default value used

请注意,默认值适用于任何函数,不仅适用于构造函数

技巧 3.(当你需要封装时)使用在伴随对象中定义的工厂方法

有时你希望你的构造函数是私有的,并且只有一个可供客户端使用的工厂方法。目前,这只能通过伴随对象中定义的工厂方法实现:

class C private (s: Int) {
    companion object {
        fun new(s: String) = C(s.length)
    }
}

用法:

val c = C.new("foo")
于 2013-10-11T05:18:37.473 回答
50

正如文档所指出的,您可以通过这种方式使用辅助构造函数

class GoogleMapsRestApiClient constructor(val baseUrl: String) {

    constructor() : this("https://api.whatever.com/")

}

请记住,您必须扩展第一个构造函数行为。

于 2016-04-24T18:01:22.230 回答
24

声明一个辅助构造函数Kotlin只需使用constructor关键字:like

这是一个主构造函数:

class Person constructor(firstName: String) {

}

或者

class Person(firstName: String) {

}

对于这样的辅助构造函数代码:

class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}

必须调用主构造函数,否则编译器会抛出以下错误

Primary constructor call expected
于 2017-07-27T14:31:55.133 回答
13

构造函数init

class PhoneWatcher : TextWatcher {

    private val editText: EditText
    private val mask: String

    private var variable1: Boolean = false
    private var variable2: Boolean = false

    init {
        variable1 = false
        variable2 = false
    }

    constructor(editText: EditText) : this(editText, "##-###-###-####")

    constructor(editText: EditText, mask: String) {
        this.editText = editText
        this.mask = mask
    }
    ...
}
于 2018-10-16T15:57:57.993 回答
7

您可以在 Kotlin 中定义多个构造函数,constructor但需要跳过默认构造函数class AuthLog(_data: String)

class AuthLog {

    constructor(_data: String): this(_data, -1)

    constructor(_numberOfData: Int): this("From count ", _numberOfData)

    private constructor(_data: String, _numberOfData: Int)

}

有关更多详细信息,请参见此处

更新

现在您可以定义默认构造函数

class AuthLog(_data: String, _numberOfData: Int) {

    constructor(_data: String): this(_data, -1) {
        //TODO: Add some code here if you want
    }

    constructor(_numberOfData: Int): this("From count", _numberOfData)

}
于 2018-04-04T18:54:49.183 回答
7

Android中具有多个构造函数的自定义视图示例:

class ShaderBackground : View {


    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        init()
    }

    private fun init() {

       // Init stuff here
        paint = Paint();
        paint.strokeWidth = 10f;
        paint.style = Paint.Style.FILL_AND_STROKE;

    }
于 2020-04-28T21:08:51.103 回答
6

回答太晚了,但这是我的谦虚贡献:)

由于 Kotlin 支持默认参数值,(注意:我想使用 null 的幂),如下所示:

data class MyClass(val a: Int? = null, val b: String? = null, val c: Double? = null)

我们不需要有多个构造函数。但即使我们想要它,我们也可以这样做:

data class MyClass(val a: Int?, val b: String?, val c: Double?){
    constructor() : this(null,null,null)
    constructor(a : Int) : this(a,null,null)
    constructor(a : Int, b: String) : this(a,b,null)
}

我们可以通过以下方式实例化这个类:

println(MyClass().toString())
println(MyClass(1).toString())
println(MyClass(1,"String").toString())
println(MyClass(1,"String",0.5).toString())

并让我们看看结果:

在此处输入图像描述

于 2019-12-02T06:32:19.813 回答
4

我刚看到这个问题,我认为可能还有另一种听起来比 Andrey 提出的技术更好的技术。

class C(a: Int) {
    class object {
        fun invoke(name: String) = C(name.length)
    }        
}

您可以编写类似val c:C = C(3)或的内容val c:C = C("abc"),因为这些方法的工作方式与Scala 中invoke的方法工作方式相同。apply

更新

到目前为止,辅助构造函数已经是语言规范的一部分,因此不应使用此解决方法。

于 2014-11-18T20:58:42.027 回答
2

下面的代码片段应该可以工作

class  C(a:Int){
  constructor(s:String):this(s.length){..}
}
于 2017-07-24T00:39:45.453 回答
1

我对大多数答案感到有些困惑。为了便于理解,我添加了一个包含更多元素的示例:

   @JsonInclude(JsonInclude.Include.NON_NULL)
   data class Response(val code: String) {
      var description: String? = null
      var value: String? = null

      constructor(code: String, description: String?) : this(code) {
          this.description = description
      }

      constructor(code: String, description: String?, value: String) : this(code, description) {
          this.value = value
      }
   }
于 2019-04-06T17:14:19.743 回答
1
class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}

你可以试试这个。

于 2017-06-11T16:26:06.450 回答
0

kotlin 辅助构造函数示例

class Person(name: String){
    var name=""
    var age=0

    constructor(age :Int,name : String)  : this(name){
        this.age=age
        this.name=name
    }
    fun display(){
        print("Kotlin Secondary constructor $name  , $age")
    }
}

主功能

fun main(args : Array<String>){

    var objd=Person(25,"Deven")
    objd.display()
}
于 2017-08-14T12:00:44.827 回答
0

使用变量“内部”,然后您可以在单个类中添加多个构造函数,如下所示。这将完美无缺。

class AuthModel {
var code: String? = null

internal constructor(code: String?) {
    this.code = code
}

internal constructor() {}
}
于 2021-01-03T09:52:58.383 回答