构造器用于在创建实例时执行初始化。构造器是创建对象的重要途径,因此Kotlin类必须包含一个或一个以上的构造器。
一、主构造器和初始化块
Kotlin类可以定义0~1
个主构造器和0~N
个次构造器。如果主构造器没有任何注解或可见性修饰符,就可以省略constructor关键字。
主构造器作为类头的一部分,可以声明形参,但它自己并没有执行体。
主构造器的形参的主要作用有如下两点:
- 初始化块可以使用主构造器定义的形参;
- 在声明属性时可以使用主构造器定义的形参。
init{
//初始化块中的可执行代码,可以使用主构造器定义的参数
......
}
初始化块中的代码可以使用主构造器定义的参数,也可以包含任何可执行语句,包括定义局部变量、调用其他对象的方法,以及使用分支、循环语句等。
class Person(name: String) {
//定义一个初始化块
init {
var a = 6
if (a > 4) {
println("Person初始化块:局部变量a的值大于4")
}
println("Person的初始化块")
println("name参数为:${name}")
}
//定义第二个初始化块
init {
println("Person的第二个初始化块")
}
}
fun main(args: Array<String>) {
Person("关羽")
}
输出结果:
Person初始化块:局部变量a的值大于4
Person的初始化块
name参数为:关羽
Person的第二个初始化块
当程序通过主构造器创建对象时,系统其实就是调用该类里定义的初始化块,如果一个类里面定义了两个普通初始化块,则前面定义的初始化块先执行,后面定义的初始化块后执行。
主构造器的主要作用就是为初始化块定义参数,因此主构造器更像是初始化块的一部分。也可以说,初始化块就是主构造器的执行体。
下面示例通过初始化块对类进行自定义的初始化操作。
class ConstructorTest(name:String,count:Int){
var name:String
var count:Int
//定义初始化块,它相当于主构造器的执行体
init {
//初始化块中的this代表其进行初始化的对象
this.name=name
this.count=count
}
}
fun main(args: Array<String>) {
var tc=ConstructorTest("三国演义",8888)
println(tc.name)
println(tc.count)
}
输出结果:
三国演义
8888
二、次构造器和构造器重载
Kotlin要求所有的次构造器必须委托调用主构造器,可以直接委托或通过别的次构造器间接委托。所谓“委托”,其实就是要先调用主构造器,然后才执行次构造器。
同一个类里具有多个构造器,多个构造器的形参列表不同,即被称为构造器重载。
class ConstructorOverload{
var name:String?
var count:Int
init {
println("初始化块!")
}
//提供无参数的构造器
constructor(){
name=null
count=0
}
constructor(name: String, count: Int){
this.name=name
this.count=count
}
}
fun main(args: Array<String>) {
//通过无参构造器创建对象
var oo1=ConstructorOverload()
//通过有参构造器创建对象
var oo2=ConstructorOverload("Kotlin",986)
println("${oo1.name} ${oo1.count}")
println("${oo2.name} ${oo2.count}")
}
输出结果:
初始化块!
初始化块!
null 0
Kotlin 986
class User(name: String) {
var name: String
var age: Int
var info: String? = null
init {
println("User的初始化块")
this.name = name
this.age = 0
}
//委托给主构造器
constructor(name: String, age: Int) : this(name) {
this.age = age
}
//委托给(String,Int)构造器
constructor(name: String, age: Int, info: String) : this(name, age) {
this.info = info
}
}
fun main(args: Array<String>) {
//调用主构造器
var user=User("刘备")
println("${user.name}=>${user.age}=>${user.info}")
var user1=User("关羽",18)
println("${user1.name}=>${user1.age}=>${user1.info}")
var user2=User("张飞",17,"丈八蛇矛")
println("${user2.name}=>${user2.age}=>${user2.info}")
}
输出结果:
User的初始化块
刘备=>0=>null
User的初始化块
关羽=>18=>null
User的初始化块
张飞=>17=>丈八蛇矛
Kotlin使用“:this(参数)
”的语法委托另一个构造器。
三、主构造器声明属性
Kotlin允许在主构造器上声明属性, 直接在参数之前使用var或val即可声明属性。
class Item(val code: String, var price: Double)
fun main(args: Array<String>) {
var item = Item("1587", 1000.0)
println(item.code)
println(item.price)
}
输出结果:
1587
1000.0
如果主构造器的所有参数都有默认值,程序能以构造参数的默认值来调用该构造器。
class Item(val code: String="123456", var price: Double=3.14)
fun main(args: Array<String>) {
var item = Item("1587", 1000.0)
println(item.code)
println(item.price)
var item2=Item()
println(item2.code)
println(item2.price)
}
输出结果:
1587
1000.0
123456
3.14
网友评论