Android kotlin 第三弹

100 阅读4分钟

类与 field

  • 自动生成 get() = field 和 set(vale) field = value field = 属性的值
  • 计算属性 编译成 java 字节代码的时候代码会省略属性成员; 只留下一个 getVersionCode(){ return 88 } 的方法
  • 只读只生成 get 方法
  • 如果定义 set 和 get 方法编译报错, 所以需要修改已定义的 set 或 get 方法

fun main() {
    val appInfo = AppInfo()
    println(appInfo.getInto())
    //自动生成
    appInfo.versionName = "?"
    println(appInfo.versionName)
    println(appInfo.versionCode)
}

class AppInfo() {
    //自动生成 get() = field 和 set(vale) field = value field = 属性的值
    var versionName: String = "1.6.90"
        get() = field.plus("1")
        set(value) {field = value}

    // 计算属性 编译成 java 字节代码的时候一下代码会省略 属性
    // 只留下一个 getVersionCode(){ return 88 } 的方法
    val versionCode:Int
        get() = 88

    //只读只生成 get 方法
    val v1 :String ="123"


    private var info: String? = null

    // this?.内置函数 + 空合并操作符号  =  防竞态条件
    fun getInto(): String {
        return info?.let {
            if (it.isBlank()) {
                "空字符"
            } else {
                "非空"
            }
        } ?: " null "
    }
}

防范竞争条件

  • this?.内置函数 + 空合并操作符号 = 防竞态条件
fun main() {
    println(AppInfo().getInto())
}

class AppInfo() {
    private var info: String? = null

    // this?.内置函数 + 空合并操作符号  =  防竞态条件
    fun getInto(): String {
        return info?.let {
            if (it.isBlank()) {
                "空字符"
            } else {
                "非空"
            }
        } ?: " null "
    }
}

主构造函数 和 init 代码块

  • 这里的主构造函数参数是没有 var val 声明,所以是临时的
  • 主构造函数会调用 init 代码块、和成员变量声明
fun main() {
    val student = Student("zhangsan", '男', 25, "?")
    println(student.sex)
}

class Student(_name: String, _sex: Char, _age: Int, _info: String) {
    val name = _name
    val sex = _sex
    val age = _age
    val info = _info
    
    init {
        println("主构造")
    }
}

次构造函数

  • 次构造函数先调用主构造,再调用自身,
  • 次构造参数是临时参数
fun main() {
    val student1 = Student1( 25, "zhangsan")
    println(student1.name)
}

class Student1(val name: String) {
    init {
        println("主构造")
    }
    constructor(age: Int, name: String) : this(name) {
        println("次构造函数${age}")
    }
}

构造函数执行顺序

  • 1-4 都是主构造的内容部分
  • 2、3、4 是同时生成,看代码顺序
  • 次构造函数先调用主构造,再调用自身,
  • 主构造函数会调用 init 代码块、成员变量声明看代码顺序
fun main() {
    val student1 = Student1( 25, "zhangsan")
    println(student1.name)
}

//第一步 生成val name
class Student1(val name: String,_info:String) {
    //第二步 生成 info 主构造中的
    val info = _info
    //第三步 成员变量
    val sex:Char ='女'
    //第四步 init代码快
    init {
        println("主构造")
    }
    //第五步 次构造函数
    constructor(age: Int, name: String) : this(name,"") {
        println("次构造函数${age}")
    }
}

lateinit 延迟初始化

  • 尽量不使用

fun main() {
    Net().getResult()
}

class Net() {

    lateinit var responseResult: String
    fun request() {
        responseResult = "result"
    }

    fun getResult(): String {
        return if (::responseResult.isInitialized) {
            "没有返回值"
        } else {
            responseResult
        }
    }
}

lazy 懒加载(调用时才加载)


suspend fun main() {
    val n = Net2()
    delay(5000)
    println(n.responseResult)
}

class Net2() {

    val responseResult: String by lazy { getResult() }

    private fun getResult(): String {
        println("....")
        return "没有返回值"
    }
}

Any 超类 Any? == Java的 Object

各个平台去实现超类 Any 的方法

对象声明 object Student3 = 单例模式


fun main() {
    //Student3.INSTANCE.show()
    Student3.show()
}

object Student3{

    init {
        println("student3 init")
    }

    fun show() = println("student3 show")

    /**
   public final static Student3 INSTANCE

    privae Student3(){}

    static{
        Student3 stu3 = new Student3()
        INSTANCE = stu3
        System.out.println("student3 init")
    }
    */
}

对象表达式 object :

  • 对象表达式 = Java的匿名内部类
  • 对 open、 抽象、接口实现类
fun main() {
    //对象表达式 = Java的匿名内部类 
    val stu4 = object : Stu4() {
        override fun add(a: String) {
            super.add(a)
            println("匿名对象 $a")
        }
    }
    stu4.add("aa")
}

open class Stu4(){
    open fun add(a:String){
        println("stu4 ${a}")
    }
}

伴生对象

  • 伴生对象是静态内部类实现
  • 伴生对象是单例的
fun main() {
    //Stu5.Companion.getName Companion是静态内部类
    Stu5.name
}

class Stu5() {
    companion object {
        val name = "伴生"
    }
}

嵌套类 和 内部类


class K20 {
    //内部类
    inner class K201 {
        inner class K2011 {
            fun getK2011() {
                println("k2011")
            }
        }
    }

    //嵌套类
    class K202 {
        fun getK202(){
            println("k202")
        }
    }
}

fun main() {
    K20().K201().K2011().getK2011()
    K20.K202().getK202()
}

数据类

  • 必须有主构造参数
  • 构造参数不能是临时参数
  • 不能 abstract open inner sealed 等修饰
  • 使用 解构component copy toString equals hashCode 内部函数就使用数据类

fun main() {
    // == 是Any超类的 equals 引用比较
    println(Stu7("7") == Stu7("7"))
    // == 数据类重写equals 对属性值进行比较
    println(Stu6("6") == Stu6("6"))
}

//普通类
//set get 构造函数
class Stu7(var name: String) {

}

//数据类
// set get 构造函数 解构component copy toString equals hashCode
data class Stu6(var name: String) {

}

数据类 copy 只执行主构造 不执行次构造

数据类 解构

fun main() {
    // == 是Any超类的equals引用比较
    println(Stu7("7") == Stu7("7"))
    // == 数据类重写equals 对属性值进行比较
    println(Stu6("6") == Stu6("6"))
    // 默认解构
    val name = Stu6("jiegou")
    println(name)
}

//普通类
//set get 构造函数
class Stu7(var name: String) {

}

//数据类
// set get 构造函数 解构component copy toString equals hashCode
data class Stu6(var name: String) {

}

运算符重载

class K22(val number: Int) {
    operator fun plus(k22: K22): Int {
        return number + k22.number
    }
   
}

fun main() {
    println(K22(1) + K22(2))
    K22(3)
}

枚举类 主要用户:状态的控制

枚举类解决不了的使用密封类

密封类


fun main() {
    val k24State = K24State.Idle
    checkState(k24State)
}

fun checkState(k24State: K24State) {
    when (k24State) {
        is K24State.Idle -> {
            println("idle")
        }
        is K24State.End -> {
            println("End")
        }
        K24State.Loading -> {
            println("Loading")
        }
    }
}

sealed class K24State {

    data object Idle : K24State()

    data object Loading : K24State()

    class End(val name: String) : K24State()

}

sealed class K24Intent {

    data object Idle : K24Intent()

    data object Loading : K24Intent()

    class End(val name: String) : K24Intent()

}

接口

接口定义

  • 接口默认是 public open 开放
  • 接口没有构造方法
  • 接口的成员和方法都需要重写实现,
  • 实现方法都需要加 override 关键字

fun main() {
    println(KK25().getVersion())
}

interface K25 {
    val name: String
    fun getVersion(): String
}

class KK25 : K25 {
    override val name: String
        get() = "niming impl"

    override fun getVersion(): String {
        return "niming version"
    }
}

抽象类和java 类似