kotlin学习之构造函数

 在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。主构造函数是类头的一部分:它跟在类名后面。

主构造函数

class Person constructor(username:String){

}

如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

class Person (username:String){

}

主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中。

class Person (username:String){
    private var name:String
   
    init {
        this.name = username
    }
}

注意:初始化块中的代码实际上会成为主构造函数的一部分。

次构造函数

类也可以声明前缀有 constructor次构造函数

如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字即可。

直接委托给主构造函数

class Person (name:String){
    private var name:String
    private var age:Int

    init {
        this.name = name
        this.age = 20
    }

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

间接委托给主构造函数

class Person (name:String){
    private var name:String
    private var age:Int
    private var address :String

    init {
        this.name = name
        this.age = 20
        this.address = "hangzhou"
    }

    constructor(name: String,age:Int):this(name){
        this.name = name
        this.age = age
        this.address = "hangzhou"
    }

    constructor(name: String,age:Int,address:String):this(name,age){
        this.address = address
    }
}

创建类的实例

要创建一个类的实例,我们就像普通函数一样调用构造函数:

  val person1 = Person("zhangsan")
  val person2 = Person("lisi",30)
  val person3 =Person("wangwu",40,"shanghai")

 注意 Kotlin 并没有 new 关键字。

完整例子

class Person (name:String){
    private var name:String
    private var age:Int
    private var address :String

    init {
        this.name = name
        this.age = 20
        this.address = "hangzhou"
    }

    constructor(name: String,age:Int):this(name){
        this.name = name
        this.age = age
        this.address = "hangzhou"
    }

    constructor(name: String,age:Int,address:String):this(name,age){
        this.address = address
    }

    fun printInfo(){
        println("name:${this.name} , age:${this.age} ,addess:${this.address}")
    }
}
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        val person1 = Person("zhangsan")
        val person2 = Person("lisi",30)
        val person3 =Person("wangwu",40,"shanghai")
        person1.printInfo()
        person2.printInfo()
        person3.printInfo()
    }
}
System.out: name:zhangsan , age:20 , addess:hangzhou
System.out: name:lisi ,     age:30 , addess:hangzhou
System.out: name:wangwu ,   age:40 , addess:shanghai

事实上,声明属性以及从主构造函数初始化属性,Kotlin 有简洁的语法:

class Person(private val name: String, private val age: Int, private val address: String) {
    fun printInfo() {
        println("name:$name , age:$age ,addess:$address")
    }
}

打印下结果

System.out: name:wangwu , age:40 ,addess:shanghai

可以正确的打印出来。说明现在构造方法中的参数中定义的name 、age、 addrress 它们就是是Person类的成员变量或者说是属性。

那么怎么区分是构造方法的参数还是类的属性呢?

我们来比对下不同

构造方法的参数,直接是(参数名:类型名)

class Person (username:String){

}

如果是成员变量(private val 参数名:类型名 )

class Person(private val name: String) {
    fun printInfo() {
        println("name:$name")
    }
}

这里有一个变量var还是常量val,还有一个可选的访问级别private,这个private是可以省略的。

这种简洁的语法在实际开发中式用的比较多。

补充一点小知识:

如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的,并且这些修饰符在它前面:

class Person public @Inject constructor(name: String) { /*……*/ }

如果我们不想外界创建这个Person类的实例,那么可以使用private来修饰。

class Person private constructor(username:String){

}

猜你喜欢

转载自blog.csdn.net/jingerlovexiaojie/article/details/106545938