• Kotlin(九)类、属性、构造函数


    1.类的属性 filed

       1)在kotlin中定义属性,必须赋初始值,要不编译器检查不通过。这个和java不同

       2)kotlin会针对于定义的每个属性都封装了一个field,用于存储数据。

       3)针对于非private的var(可变)属性,kotlin默认会生成一组getter和setter方法,通过反编生成的byteCode代码可以看到定义的setter和getter方法。

       4 )针对于非private的val(不可变)属性,kotlin只生成了getter方法,没有setter方法,因为定义为val的属性,是不允许修改的。

      5)我们也可以在属性后面,复写getter和setter方法,自己定义要实现的内容。

      6)针对于private关键字修饰的属性,kotlin不对外提供setter和getter方法。尽管我们能够复写这两个方法。外界还是不能够访问。这点和Java有很大的不同。

    1. class Person {
    2. //针对于定义的每个属性,都有一个filed进行封装。
    3. //对于非private的属性,都会生成一对getter和setter方法
    4. //我们也可以自己定义这俩方法
    5. var name = ""
    6. get() = field.plus("_01")
    7. set(value) {
    8. field = value.uppercase()
    9. }
    10. //对于val的属性,kotlin不听过setter方法
    11. val age = 0
    12. get() = field + 1
    13. //对于private属性,kotlin不提供getter和setter方法。
    14. //虽然我们已经复写了,但是外界还是不够能访问,这个和java的区别很大。
    15. private var subject = ""
    16. get() = "Kotlin"
    17. set(value) {
    18. field = value
    19. }
    20. }
    21. fun main() {
    22. val person = Person()
    23. person.name = "LiLei"
    24. println(person.name)
    25. println(person.age)
    26. }

    2.构造函数

    1)定义在class 类名 后面的构造函数,是类的主构造函数。这个和java不一样,可以直接定义在类上

    2)在主构造函数中,可以使用临时变量给类属性赋值,为了方便识别,在kotlin中,临时变量通常会以下划线开头_属性名。如_name:String

    3)在主构造函数中,可以同时定义临时变量和类属性,要加上var或val修饰符。如var age:Int

    4)在属性参数后直接设置默认值。创建对象时,默认参数可以不传。如var subject:String="Kotlin"

    5通过 constructor() : this可以定义次构造函数

    6)通过init{}定义初始化块,对所传参数进行有效性检查。初始化块会在构造类实例时执行。

    1. //定义在class 类名 后面的构造函数,是类的主构造函数。
    2. //在主构造函数中,可以使用临时变量给类属性赋值,为了方便识别,在kotlin中,临时变量通常会以下划线开头_属性名。
    3. //也可以在主构造函数中,可以同时定义临时变量和类属性,要加上var或val修饰符。
    4. //还可以在属性后直接设置默认值。创建对象时,默认参数可以不传。
    5. class Person(_name: String, var age: Int, var subject: String = "Kotlin") {
    6. var name = _name
    7. get() = field.plus("_01")
    8. set(value) {
    9. field = value.lowercase()
    10. }
    11. //次构造函数
    12. constructor(_name: String, _age: Int) : this(_name, _age, "Java"){
    13. this.name = _name.trim()
    14. }
    15. //无参是次构造函数
    16. constructor() : this("", 1, "")
    17. //初始化代码块
    18. init {
    19. //通过require函数,对属性值做合规判断。如果
    20. require(age > 0) { "age must be >0" }
    21. require(name.isNotEmpty()){"name can not be empty"}
    22. }
    23. }
    24. fun main() {
    25. val person = Person("LiLei ", 18)
    26. println(person.name)
    27. println(person.age)
    28. println(person.subject)
    29. }

    3.执行顺序

      对应属性,可以通过主构造函数、类属性、初始化代码块、和次级构造函数,来进行初始化。

    那么他们的执行顺序就是上面这个顺序。这个执行顺序要牢记,很关键,有可能会踩到坑。

    4.延迟初始化

     通过 lateinit这个关键字,实现延迟初始化。属性可以在声明时,不必赋初始值。但是在使用前必须赋值。可以通过 ::hobby.isInitialized 这个来判断是否初始化完成。

    1. lateinit var hobby:String
    2. fun initHobby(){
    3. hobby="game"
    4. }
    5. fun isInit():Boolean{
    6. //判断属性是否初始化
    7. return ::hobby.isInitialized
    8. }

    5.惰性初始化。

      通过by lazy可以实现惰性初始化。属性声明时不必赋值,使用这个属性时,会自动初始化。

    1. val lazy by lazy { lazyinit() }
    2. private fun lazyinit() :Boolean{
    3. println("lazy init")
    4. return true
    5. }

  • 相关阅读:
    汉诺塔问题
    怎样通过jQuery属性操作实现不同功能需求
    C++ 函数
    基于机器学习建模的 XSS 攻击防范检测
    360T7路由器进行WiFi无线中继教程
    PowerBI-窗口函数-INDEX
    kafka知识笔记
    ubuntu安装docker
    C语言之文件的使用(下)
    2022-09-11 周总结
  • 原文地址:https://blog.csdn.net/niuyongzhi/article/details/126575708