Kotlin中的一些常用关键字以及特性

关键字

  1. Object:

    1. 简化生成静态内部类

    2. 生成匿名内部类对象

    3. 生成单例对象

      如果object只是声明,它代表一个静态内部类。如果用变量接收object表达式,它代表一个匿名内部类对象。

    object Admin {
        private var username = "admin"
        private var password = "admin"
    
        fun info(): String {
            return "${this.username}/${this.password}"
        }
    
        fun changePassword(password:String){
            this.password = password
        }
    }
    
    fun main(args: Array<String>) {
        Admin.changePassword("new-password")
        println(Admin.info()) // admin/new-password
    }
    
  2. 伴生对象:

    1. 可以把伴生对象看成是一个普通Java类的单例对象,因为它最终也是按照普通类对象进行编译的,只不过默认给你生成了一个唯一的实例。
    2. Kotlin为什么没有static的东西,我觉得第一个原因是我们不仅可以引用一个kt文件中的类,也可以引用它所定义的变量以及方法,完全可以用这种方式实现所谓的静态属性以及静态方法;如果前面的方式不能满足需求,companion object带给我们的优势是我们可以像对待其他普通类一样继承类或实现接口,相对于static class给我们带来了更大的自由度
    class Admin {
    
        companion object {
            private var username = "admin"
            private var password = "admin"
    
            fun info(): String {
                return "${this.username}/${this.password}"
            }
    
            fun changePassword(password:String){
                this.password = password
            }
        }
    }
    
    fun main(args: Array<String>) {
        Admin.changePassword("new-password")
        println(Admin.info()) // admin/new-password
        Admin.changePassword("new-password2")
        println(Admin.info()) // admin/new-password2
    }
    
  1. By:

    1. 类的代理 class

      //kotlin代理 编译后实为java中的静态代理
      interface Animal{
          fun bark()
      }
      
      class Dog : Animal {
          override fun bark() {
              println("DOG's Bark()")
          }
      }
      
      class Zoo(animal: Animal) : Animal by animal {
          override fun bark() {
              println("ZOO’s Bark")
          }
      }
      
      fun main(args: Array<String>) {
          Zoo(Dog()).bark()
      }
      
      
      interface Base {
          val message: String
          fun print()
      }
      
      class BaseImpl(val x: Int) : Base {
          override val message = "BaseImpl: x = $x"
          override fun print() { println(message) }
      }
      
      class Derived(b: Base) : Base by b {
          // 在 b 的 `print` 实现中不会访问到这个属性
          override val message = "Message of Derived"
        //但是在复写了print方法后,执行的依然是Derived的print方法调用的本类中的成员变量
      //    override fun print() {
      //        println(message)
      //    }
      }
      
      fun main() {
          val b = BaseImpl(10)
          val derived = Derived(b)
          derived.print()
          println(derived.message)
      }
      
    2. 属性延迟加载 lazy

    3. 监听属性变化 Delegates.observable ( 扩展 Delegates.vetoable )

    4. 自定义监听属性变化 ReadWriteProperty

    5. 属性非空强校验 Delegates.notNull()

    6. Map值 映射到类属性 map

  2. inner

    1、inner修饰的内部类可理解为java中的非静态内部类,调用方式:

    外部类().内部类().方法();

    2、kotlin内部类默认为静态的,理解为java中使用static修饰的内部类,调用方式:

    外部类.内部类().方法();

    3、如果需要在静态内部类中使用外部类,可参考java中实现方式,在内部类中定义外部类弱引用,通过构造方法传入外部类对象;

    class InnerTest{
        var a=5
    
        class NotInner{
            fun m1(i: Int):Int {
    //            a=i  编译不通过
                return i + 1
            }
        }
    
        //inner修饰过的内部类可以访问外部内成员变量
        inner class WithInner{
            fun m2(i: Int):Int {
                a=i
                return a
            }
        }
    }
    
    
    fun main(args: Array<String>) {
        print(InnerTest.NotInner().m1(5)) //调用没有被inner修饰过的内部类时,外部类不需要被实例化,类似与java中的静态内部类
        print(InnerTest().WithInner().m2(5)) //InnerTest类需要实例化才能调用被inner修饰过的内部类
    
    }
    
  3. 解构Operator:

    1. 无date关键词

      //解构 方法体必须声明为componentN()
      class Boy(var age: Int, var name: String){
          operator fun component1()=age
          operator fun component2()=name
      }
      
      
      
      fun main(args: Array<String>) {
          var p1 = Person(19, "张三", "张二狗")
          var(age,name,lastname)=p1
      }
      
    2. 有date关键字

      //数据类中自带了operator操作符,无需使用componentN()函数
      data class Person(val age: Int, val name: String, val lastName: String)
          
          
      fun main(args: Array<String>) {
          var (age, name) = Boy(15, "珠海")
      }
      
  4. 循环

    for(i in 1..10){}//包括10
    for(i in 1 until 10) //不包括10
    for(i in 10 downTo 1)
    for(i in 1..10 step 2) //步进2
    repeat(10){} //循环10次 
    
//循环list
val testList = listOf<String>("a", "b", "c")
for ((index, value) in testList.withIndex()) {
        print(index.toString()+value)
 }
  1. 作用域函数

    //返回lambda表达式结果
    run{...}
    let{...}
    with(T){...}
    //返回上下文对象
    apply{...}
    also{...}
    
  1. Lambda闭包

     val echo = { name: String -> print(name) }
     echo.invoke("张三")//invoke 调用,操作符重载 等价于下面一条语句
     echo("王二")
    
  1. 高阶函数(使用闭包函数作为参数传入)
//高阶函数
fun onlyif(age:Int,isDebug: Boolean, block: (a:Int) -> Unit) {
    if (isDebug){
        block(age)
    }
}
fun main(args: Array<String>) {
    val lam:(a:Int)->Unit//lambda声明

    lam={ print(it + 1)} //lambda表达式实现

    onlyif(5,true,lam)//调用方法,传入参数
}
  1. inline

通过该关键字来优化代码,编译器将使用函数的定义体来替代函数调用语句,这种替代行为发生在编译阶段而非程序运行阶段

 fun plus(i: Int){
     i += 1
 }
 //该段代码会报Val cannot be reassigned的错误,因为kotlin是直接值传递,而java在值传递时候形参实际上是经过一次复制后的新值(内存地址改变,value不变)
  1. sealed关键字

    sealed class CompareResult{
        object Less:CompareResult() {
            override fun toString(): String {
                return "小于"
            }
        }
        object More : CompareResult() {
            override fun toString(): String {
                return "大于"
            }
        }
        object Equals : CompareResult() {
            override fun toString(): String {
                return "相等"
            }
        }
    }
    //一旦使用密封类就要用完密封类中所有的子类,不然会编译期报错
    fun check(cr: CompareResult):String {
        when (cr) {
            is CompareResult.Equals -> return cr.toString()
            is CompareResult.More -> return cr.toString()
            is CompareResult.Less -> return cr.toString()
        }
    }
    
    infix fun Int.vs(num: Int): CompareResult =
        if (this > num) {
            CompareResult.More
        }else if (this < num) {
            CompareResult.Less
        }else{
            CompareResult.Equals
        }
    
    fun main(args: Array<String>) {
        print(7 vs 7)
    }
    
  2. infix关键字

    使用该关键字进行操作符重载

    infix fun Int.vs(num: Int): CompareResult =  //自定义了一个操作符vs 该操作符是以拓展函数的放法添加在目标类上的。
        if (this > num) {
            CompareResult.More
        }else if (this < num) {
            CompareResult.Less
        }else{
            CompareResult.Equals
        }
    
    fun main(args: Array<String>) {
        print(7 vs 7)
    }
    
  3. enum枚举

    enum class AE(var age: Int, var lname: String) {
        A(14, "张三") {
            override fun a(a: Int): Int = a + 1
        },
        B(15, "王二") {
            override fun a(a: Int): Int = a + 2
        };
    
        //抽象方法,需要枚举实例自己实现方法
        abstract fun a(a: Int): Int
    
        //每个枚举实例都默认实现该方法跟java枚举一样
        fun b(str: String): String = str + this.lname
    }
    
    fun check(a: AE) {
        when (a) {
            AE.A -> print(a.lname)
            AE.B -> print(a.age)
        }
    }
    
    fun main(args: Array<String>) {
        check(AE.A)
    }
    
  4. 比较是否相等
    java kotlin
    a==b -> a ===b
    a.equals(b) -> a==b

  5. 集合

    kotlin中的集合默认为只读类型,可变类型是在不可变类型前添加Mutable

    获取一个新集合

    
    var nums= mutableListOf<Int>()
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容