类的构造方法

  • 构造方法
  • 主构造函数
  • 初始化代码块
  • 次构造函数
  • 无参构造函数
  • 实例
  • 参考地址


构造方法

在Kotlin中,允许有一个主构造函数和多个二级构造函数(次构造函数)。

其中主构造函数是类头的一部分,关键字或者构造函数名:constructor(参数)

主构造函数

也就是说,当你创建一个类的时候,其实已经创建了它的构造函数,只是它是无参的

如下,它省略了 constructor 关键字

class Student {
    
}

其实应该写成:

class Student public constructor() {

}
//或者
public class Student constructor() {

}

如果添加参数:

class Student constructor(num: Int) {
    init {
        println("num ==$num")
    }
}

init() 是主构造方法的初始化方法(也称为初始化代码块

也就是说主构造方法被调用后,会调用init()这个方法,初始化数据,主构造方法内的参数,init()方法可以使用。

初始化代码块

同时,初始化代码块也可以定义多块:

class Student constructor(num: Int) {
    init {
        println("初始化代码块1 num ==$num")
    }
    init {
        println("初始化代码块2")
    }
}

调用

var student = Student(1)

打印

2022-01-05 22:22:04.920 28791-28791/com.example.kotlintest3 I/System.out: 初始化代码块1 num ==1
2022-01-05 22:22:04.920 28791-28791/com.example.kotlintest3 I/System.out: 初始化代码块2

初始化代码块在主构造函数调用的时候,会按声明顺序,顺序执行

次构造函数

续写个次构造函数,格式演示如下:

class Student constructor(num: Int) { //主构造函数

    init { //主构造函数的初始化方法
        println("num ==$num")
    }

    constructor(name: String) : this(233) { //次构造函数
        println("name ==$name")
    }
}

对于次构造函数,在没有继承的场景下,Kotlin要求次构造函数必须与其他构造函数有调用关系,并最终调用到主构造函数,通过:

: this(*)

这个 this() 可以调用主构造函数或者其他次构造函数,如上就是调用主构造函数

如果想调用次构造函数:

class Student constructor(num: Int = 1) {

    init {
        println("初始化代码块1 num ==$num")
    }

    constructor(name: String) : this() { //次构造函数1
        println("name ==$name")
    }

    constructor(name: String, height: Int) : this(name) { //次构造函数2
        println("name ==$name")
    }

}

如上,如果调用次构造函数2,次构造函数2会调用次构造函数1,次构造函数1会调用主构造函数。嗯,最终会调用到主构造函数。

如果是继承的场景下,Kotlin的子类可以没有主构造函数,但是最终需要调用到父类的主构造函数。

通过

:super(*)

无参构造函数

1.我们知道创建一个Kotlin类,默认就会有个无参构造函数,

class Student {
    
}

可以通过 var student = Student() 创建

2.如果我们给它添加上参数,无参构造函数将会消失,转而主构造函数变成有参的了。

class Student constructor(num: Int) {
	....
}

var student = Student() 将会编译错误,转而 var student = Student(1) 可以创建

3.那么是否还可以拥有无参构造函数呢,答案是肯定的。

只要我们为参数设置默认值,就可以了

class Student constructor(num: Int = 1) {
	....
}

var student = Student() 和 var student = Student(1) 都可以创建student

但是这个时候 var student = Student() 和之前1中不一样,这个构造函数不是调用了无参构造函数,而是调用了有参构造函数,只是该函数有默认值,允许这么调用。

4.如果主构造函数和次构造函数都设置默认值,那么 var student = Student() 调用的是谁的呢?

如下,允许编译:

class Student constructor(num: Int =1) {

    init {
        println("初始化代码块1 num ==$num")
    }
    
    constructor(name: String = "name", height: Int = 2) : this() {
        println("name ==$name")
    }
}

但是,不允许编译:

class Student constructor(num: Int =1) {

    init {
        println("初始化代码块1 num ==$num")
    }

    constructor(name: String = "name") : this() {
        println("name ==$name")
    }
}

允许编译:

class Student constructor(num: Int =1) {

    init {
        println("初始化代码块1 num ==$num")
    }
    constructor(name: String = "name",w :Long = 1) : this() {
        println("name ==$name")
    }
    constructor(name: String = "name", height: Int = 2) : this() {
        println("name ==$name")
    }

}

可以看到,主要和主构造函数参数数量不一致,编译还是可以的。但是调用还是调用的主构造函数的无参函数。

实例

//长整型 64位 注意后面加大写L
        var height: Long? = null
        var height3: Long = 0L

        //整型 32 位
        var id: Int? = null
        var id2: Int = 0

        //短整型 16位
        var short: Short? = 0
        var short2: Short = 0

        // 8位
        var byte: Byte? = null
        var byte2: Byte = 0

        //浮点类型 双精度  64位
        var level: Double = 0.0
        var level2: Double? = null

        //单精度  后面加f
        var float: Float = 0.0f
        var float2: Float? = null

        //时间类型成员属性
        var createTime: Date? = null

        //初始化,kotlin没有new关键字,直接 对象()就是创建一个新对象
        var time: Date? = Date()

        //字符串类型
        var introduction: String? = null

        //布尔类型作为属性
        var isHide: Boolean? = null

        //可变集合作为属性
        var child: MutableList<Student>? = null

        // Char是一个单独类型 ,不表示数字,需要用‘’括起来,不然那会报错
        var char: Char? = '1'
        var char2: Char = '1'

转 Kotlin中实体类的创建:

如果是嵌套类和内部类

class Student constructor() {
    class English {

    }
    inner class Teacher {

    }
}

则:

var english = Student.English()
        var teacher = Student().Teacher()

参考地址

Kotlin中实体类的创建: