kotlin基础知识一

194 阅读7分钟

kotlin基本常识处理

1. 基本数据处理

1.1 get和set的处理

格式上和 Java 有一些区别:

  • getter / setter 函数有了专门的关键字 get 和 set

  • getter / setter 函数位于 var 所声明的变量下面

  • setter 函数参数是 value

    除此之外还多了一个叫 field 的东西。这个东西叫做「Backing Field」。这个 field 对编码的人不可见,但会自动应用于 getter 和 setter,因此它被命名为「Backing Field」。在 Kotlin 里,它相当于每一个 var 内部的一个变量。

    class User {
        var name = "Mike"
            👇
            get() {
                return field + " nb"
            }
            👇   👇 
            set(value) {
                field = "Cute " + value
            }
    }
    

    1.2 Constants in Kotlin

    1.1.1 静态常量

    • Companion object

    Kotlin中没有static关键字,如果你想在类中声明静态方法或属性,就要把他们放在companion object(伴生对象)中。

    class Constants { companion object { val FOO = "foo" } }

    • const val

      使用条件

    1. 作为顶层属性、companion object属性,或object属性
    2. 只可修饰String或原始类型
    3. 不能自定义getter

    class Constants { companion object { const val FOO = "foo" } } // 静态常量

    • JvmField

    把上面const去掉,给FOO加上JvmField注解 生成的Java代码原文没给

    class Constants { companion object { @JvmField val FOO = Foo() //Foo()是为了说明不限定于原始类型 } }

    eg:

    class Constants {
    ​
        companion object{
           const val data = 5
        }
    }
    

    1.1.2 Top-Level

    如果一个类只是用来装载常量,那我们可以放心大胆地“丢弃这个类和companion object”,使用Kotlin的文件级属性(顶层属性) 直接在kt文件中

    const val FOO = "foo"

    生成对应的Java代码(或许就是你在使用Java时会写上的代码)

    public final class ConstantsKt {
       @NotNull
       public static final String FOO = "foo";
    }
    

    eg:

    const val data = 5
    

    1.3 NULL检查机制

    Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做空判断处理

    //类型后面加?表示可为空
    var age: String? = "23" 
    //抛出空指针异常
    val ages = age!!.toInt()
    //不做处理返回 null
    val ages1 = age?.toInt()
    //age为空返回-1
    val ages2 = age?.toInt() ?: -1
    

    1.3.1 基本函数的使用

    private fun dataTest(){
        Log.d(TAG, "test the data:$data")
        var result = add(5,6)
        mText?.text = "$result"
        Log.d(TAG, "test the data:$result")
    }
    ​
    private fun add(a:Int,b:Int):Int{
        return a+b
    }
    ​
    对于当前的变量值尽量使用$来 
    

    1.4 字符串模板

    $ 表示一个变量名或者变量值

    $varName 表示变量值

    ${varName.fun()} 表示变量的方法返回值:

    1.5 区间

    区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。

    区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。以下是使用区间的一些示例:

    1.6 延迟初始化

    具体是这么写的:

    🏝️
    lateinit var view: View
    

    这个 lateinit 的意思是:告诉编译器我没法第一时间就初始化,但我肯定会在使用它之前完成初始化的。

    它的作用就是让 IDE 不要对这个变量检查初始化和报错。换句话说,加了这个 lateinit 关键字,这个变量的初始化就全靠你自己了,编译器不帮你检查了。

    1.7 类和对象

    1) 类的继承的写法,Java 里用的是 extends,而在 Kotlin 里使用 :,但其实 : 不仅可以表示继承,还可以表示 Java 中的 implement

    2)使用 is 关键字进行「类型判断」,直接进行强转调用呢?可以使用 as 关键字

    1.8 延迟初始化的实现

    lateinit 只用于变量 var,而 lazy 只用于常量 val

    lazy 应用于单例模式(if-null-then-init-else-return),而且当且仅当变量被第一次调用的时候,委托方法才会执行。

    lazy()是接受一个 lambda 并返回一个 Lazy <T> 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。

    val lazyValue: String by lazy {
        println("computed!")
        "Hello"
    }
    ​
    fun main(args: Array<String>) {
        println(lazyValue)
        println(lazyValue)
    }
    ​
    打印结果
    computed!
    Hello
    ​
    Hello
    

    1.9 by 关键字的使用

    Kotlin 中 by 关键字用来简化实现代理 (委托) 模式,不仅可以类代理,还可以代理类属性, 监听属性变化,下面我们来介绍by的几种主要使用场景:

    • 类的代理 class

    • 属性延迟加载 lazy

    • 可观察属性 Delegates.observable ( 扩展 Delegates.vetoable )

    • 自定义监听属性变化 ReadWriteProperty

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

    • Map值 映射到类属性 map

      private val model: NameViewModel by viewModels()
      

2.1 kotlin创建数组

(1)Kotlin语言使用Array表示数组。

(2)[] 可以用于访问数组的元素, [] 被进行了操作符的重载,调用的是 Array 类的 setter 和 getter 方法

2.1.1 创建空数组

val arrayEmpty = emptyArray<String>()

2.1.2 创建指定长度的空数组

val array1 = arrayOfNulls<Int>(5)
for (i in 0..4) {
    array1[i] = i
}

2.1.3 创建指定长度的数组

val array4 = Array(5, {0})

初始化长度为5,元素均为0的数组

val array5 : Array<String> = Array(5, {""})
for (i in 0..2) {
    array5[i] = i.toString()
}

初始化长度为5,元素均为""的数组,并为数组前3个元素赋值,"0", "1", "2", "", ""

2. 1. 4 使用kotlin封装创建数组

val array1 = arrayOf(1, 2, 3, 4)
val array2 = intArrayOf(1, 2, 3, 4)

2.1.5 遍历数组

val array7 = Array(4, { i -> i * i }) //0,1,4,9,16

// 遍历数组元素 for (item in array7) { println(item) }

// 遍历数组下标 for (item in array7.indices) { println(item) }

// 迭代器遍历数组1 val it = array7.iterator() for (item in it.iterator()) { println(item) }

// 迭代器遍历数组2 val it1 = array7.iterator() it1.forEach { println(it) }

// forEach遍历数组 array7.forEach { println(it) }

2.2 集合处理

image.png

主要有三個類別:

  • List:可儲存重複值,用索引值 (Index) 取值,為有序排列。
  • Set:儲存在 Set 的內容都是唯一的,為無序排列。
  • Map* :採用 Key-Value 的方式儲存,用 Key 可以取得 Value。

註:Map 雖然不是繼承 Collection,但仍歸納於集合函數內。

上面三個類別都是不可修改內容的,也就是說當 List Set Map 建立出來之後,就無法修改其內容了。但是,個別有一個可以繼承原類型可修改的類型:

  • MutableList:可修改的 List。
  • MutableSet:可修改的 Set。
  • MutableMap:可修改的Map。

2.3 object是Kotlin中的一个重要的关键字,也是Java中没有的。

object是Kotlin中的一个重要的关键字,也是Java中没有的。object主要有以下三种使用场景:

  • 对象声明(Object Declaration)
  • 伴生对象(Companion Object)
  • 对象表达式(Object Expression)

2.3.1 对象声明(Object Declaration)

  1. 语法含义:将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式) 2) 基本示例

object RepositoryManager{ fun method(){ println("I'm in object declaration") } } 即将class关键字替换为object关键字,来声明一个类,与此同时也声明它的一个对象。只要编写这么多代码,这个类就已经是单例的了。

代码测试验证:fun main(args: Array) { RepositoryManager.method() }

2.3.2 伴生对象(Companion object)

在Kotlin中是没有static关键字的,也就是意味着没有了静态方法和静态成员。那么在kotlin中如果要想表示这种概念,取而代之的是包级别函数(package-level function)和我们这里提到的伴生对象。

class A{ companion object 伴生对象名(可以省略){ //define method and field here } }

2.3.3 对象表达式(Object Expression)

该对象表达式,实现的就是java中匿名内部类的功能。

b. 一个匿名内部类肯定是实现了一个接口或者是继承一个类,并且只能是一个,用数学术语说是“有且只有一个”

  1. 语法形式:

object [ : 接口1,接口2,类型1, 类型2]{} //中括号中的可省略

  1. 使用示例:

a. 实现一个接口或类

interface AA { fun a() }

fun main(args: Array<String>) {
val aa = object : AA {
    override fun a() {
        println("a invoked")
    }
}
​
aa.a()
}

b. 实现多个接口和类

fun main(args: Array<String>) {
    val cc = object : AA, BB() {
        override fun a() {
  }
​
    override fun b() {
​
    }
​
}
​
cc.a()
cc.b()
​
}

2.4 when的使用

  1. 可以实现switch的功能
  2. when也可以作为一个表达式

2.5 Any的使用

2.5.1 基本数据类型

在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。Byte、Short、Int、Long、Float、Double 、Char