#概述#
在Kotlin中类可以有一个主构造函数以及多个二级构造函数。 主构造函数是类头的一部分:跟在类名后面(可以有可选的参数)。
class Person(val name : String, val age : Int) {
override fun toString(): String{
return "Person(name='$name', age=$age)"
}
}
fun main(args: Array<String>) {
val personA: Person = Person("li", 20)
val personB: Person = Person("wang", 30)
println("personA:${personA.toString()}")
println("personB:${personB.toString()}")
}
// Log打印
personA:Person(name='li', age=20)
personB:Person(name='wang', age=30)
从示例代码中,可以看出主构造函数中,两个参数name和age。在创建Person对象时,必须传递这两个参数。如果不传递会提示上图错误。
##主构造函数及初始化代码块
主构造函数不能包含任意代码,只能声明构造函数的参数。若想初始化代码,放在以init做前缀的初始化块内。
class Person(var name : String, var age : Int) {
init {
name = "zhang"
println("Person init")
}
override fun toString(): String{
return "Person(name='$name', age=$age)"
}
}
fun main(args: Array<String>) {
val personA: Person = Person("li", 20)
val personB: Person = Person("wang", 30)
println("personA:${personA.toString()}")
println("personB:${personB.toString()}")
}
// Log打印
Person init
Person init
personA:Person(name='zhang', age=20)
personB:Person(name='zhang', age=30)
从Log打印可以看出
- 每次Person创建对象时,都会调用init初始化代码块。
- 若在init初始化代码块中,对对象的属性值初始化,该属性的值为以init初始化代码块中最后一个赋值,并不是通过主构造函数传递的值。
- 主构造函数中的参数若不设置为var或val,默认为val,其值不可修改。
- init初始化代码块,不仅能够初始化属性,同时可以做相应逻辑处理
如果主构造函数有注解或可见性声明,则constructor关键字是不可少的,并且注解
应该在前:
calss Customer public inject constructor (name: String) {...}
##二级构造函数
类的二级构造函数以constructor为前缀,例如
class Person(var name : String, var age : Int) {
constructor( name: String, age: Int,val addr: String) : this(name, age) {
}
}
如果类有主构造函数,每个二级构造函数都要或直接或间接通过另一个二级构造函数代理主构造函数。如果在同一个类中代理另一个构造函数,应使用 this 关键字。
class Person(var name : String, var age : Int) {
constructor( name: String, age: Int, addr: String) : this(name, age) {
}
constructor(name: String, age: Int, addr: String, sex: Int) : this(name, age, addr){
}
}
注:
- 二级构造函数的参数不能设定为var或val,但默认为val类型
2. 主构造函数里面的参数即为该类的属性,而二级构造函数中的参数,只是参数,并不是该类的属性。
3. 在JVM虚拟机中,如果主构造函数的所有参数都有默认值,编译器会生成一个无参的构造函数。
class Student(val name : String = "A", val age : Int = 10) {
}
// 创建实例
val stuA = Student()
-
如果一个非抽象类没有声明构造函数(主构造函数或二级构造函数),它会产生一个没有参数的构造函数。
-
构造函数的权限修饰符为public。如果想的类有公共的构造函数私有化,你就得声明一个空的主构造函数,并用private修饰
class DontCreateMe private constructor () { }
#创建类的实例
val invoice = Invoice()
val customer = Customer("Joe Smith")
注:Kotlin中并没有new关键字
#类的成员
- 构造函数
- 初始化代码块
- 函数
- 属性
- 包含内部类
- 对象声明
#final和open
所有的类默认都是不可继承的,即默认被final修饰符修饰。故在创建一个类,并作为父类时,需手动添加open或者abstract关键字,以声明此类可被继承。
open class Animal(name: String)
class Person(name: String, surname: String) : Animal(name)