Kotlin主要构造函数调用次要构造函数

时间:2018-08-02 15:40:10

标签: kotlin class-constructors multiple-constructors

为什么不编译?

class test
{
  constructor() {
      var a = Date().day
      this(a)
  }

  constructor(a:Int) {
  }
}

错误是: 类型为“ test”的表达式“ this”不能作为函数调用。找不到函数“ invoke()”。

建议的解决方法是添加以下内容:

private operator fun invoke(i: Int) {}

为什么?

3 个答案:

答案 0 :(得分:5)

首先,这两个构造函数都是辅助构造函数。主要构造函数是位于类主体外部的构造函数。

第二,如documentation中所述,调用另一个构造函数的正确语法如下:

class Test {
    constructor() : this(1) { }

    constructor(a: Int) { }
}

答案 1 :(得分:0)

class test constructor(){ // primary constructor (The primary constructor is part of the class header: it goes after the class name (and optional type parameters))

    constructor(a: Int) : this() { // secondary constructor

    }
}

如果您的班级定义了primary constructor,则secondary constructor需要委托给primary constructor。参见here

我认为无法从primary constructor呼叫secondary constructor

您可以这样认为:次要呼叫主要和次要呼叫次要=>无限循环=>不可能

根据您的情况,有2个secondary constructor,所以您可以喜欢

class test {

    constructor() : this(Date().day) // I see it quite like Java here https://stackoverflow.com/questions/1168345/why-do-this-and-super-have-to-be-the-first-statement-in-a-constructor

    constructor(a: Int) {
    }
}

答案 2 :(得分:-2)

这里的事情错了:

  • 类的名称应始终使用驼峰式(test-> Test
  • 您无法像尝试那样调用其他构造函数(在其他构造函数主体内部调用this(1)

我认为您真正想要的是a作为属性,或者使用默认值对其进行初始化。你可以这样做

class Test(val a: Int) {
    constructor() : this(1) // notice how you can omit an empty body
}

甚至更好,例如:

class Test(val a: Int = 1) // again an empty body can be omitted.

编辑:

如果您需要进行一些计算,请按照Yole答案下方的评论中的要求进行:

class Test(val day: Int) {
    // you can use any expression for initialization
    constructor(millis: Long) : this(Date(millis).day) 
}

或者情况变得更复杂:

class Test(var day: Int) {
    // pass something (i.e. 1) to the primary constructor and set it properly in the body
    constructor(millis: Long) : this(1) { 
        // some code
        day = // initialize day
    }
}