空重载构造函数

Null overload constructor

我有以下 class.

class Student(id: String, name: String) {

    var id: String? = null
    var name: String? = null
    var grade: String? = null

    constructor(id: String, name: String, grade: String) : this(id,name) {
        this.grade = grade
    }
}

使用:

  var student = Student("AB001","Smith","N/A")

  prinln(student.id + student.name + student.grade)

输出:

nullnullN/A

任何人都可以解释为什么我从默认构造函数中得到输出 null 吗?

class Student {
    var id: String? = null
    var name: String? = null
    var grade: String? = null

    constructor(id: String, name: String) {
        this.id=id
        this.name=name
    }

    constructor(id: String, name: String, grade: String) : this(id, name) {
        this.grade = grade
    }
}

class Student(var id: String?, var name: String?) {
    var grade: String? = null

    constructor(id: String, name: String, grade: String) : this(id, name) {
        this.grade = grade
    }
}

class Student(id: String, name: String) {
    var id: String? = null
    var name: String? = null
    var grade: String? = null

    init {
        this.id = id
        this.name = name
    }

    constructor(id: String, name: String, grade: String) : this(id,name) {
        this.grade = grade
    }
}

init 块是您在主构造函数中使用参数的方式,当它们在那里没有标记为 vals 或 vars 时必须这样做。

换句话说,由于您没有将主构造函数中的参数(class 名称旁边的括号)标记为 vals 或 vars,因此它们不会自动分配为属性。为了在主构造函数中使用参数,尤其是那些没有标记为 vars 和 vals 的参数,您需要一个 init 块。

我不禁认为你真正想要的是这个不过:

class Student (var id: String, var name: String, var grade: String? = null)

甚至可以将它们更改为 vals 而不是 vars。

除了其他答案,还有一个办法。直接使用主构造函数参数初始化属性:

class Student(id: String, name: String) {

    var id: String? = id
    var name: String? = name
    var grade: String? = null

    constructor(id: String, name: String, grade: String) : this(id,name) {
        this.grade = grade
    }
}

请注意,由于 idname 始终使用 non-nullable 值进行初始化,因此您可以省略 ?。除此之外,您可以使用主构造函数中的默认值省略辅助构造函数:

class Student(id: String, name: String, grade: String? = null) {

    var id: String = id
    var name: String = name
    var grade: String? = grade

}

但是现在我们只剩下一个构造函数,所以我们可以直接将属性拉入构造函数:

class Student(
        var id: String,
        var name: String, 
        var grade: String? = null
)

因为 class 的正文现在是空的,所以我也省略了大括号。