Kotlin 二次构造函数

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

有相关文件吗?

以下不编译..。

class C(a : Int) {
// Secondary constructor
this(s : String) : this(s.length) { ... }
}
131955 次浏览

更新 : 因为 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")

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

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

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

更新

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

作为 文件要点,您可以以这种方式使用辅助构造函数

class GoogleMapsRestApiClient constructor(val baseUrl: String) {


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


}

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

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

你可以试试这个。

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

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

要声明辅助构造函数 科特林,只需使用 构造函数关键字: 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

辅助构造函数示例

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()
}

你可以在 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)


}

使用 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
}
...
}

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

   @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
}
}

现在回答为时已晚,但这里是我的微薄贡献:)

由于 Kotlin 支持缺省的 param 值(注意: 我想使用 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())

让我们看看结果:

enter image description here

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;


}

使用’内部’变量,然后你可以添加多个构造函数在单个类如下。这将工作得天衣无缝。

class AuthModel {
var code: String? = null


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


internal constructor() {}
}