美文网首页Kotlin开发知识
Kotlin for android学习一:基础知识

Kotlin for android学习一:基础知识

作者: crossroads | 来源:发表于2017-09-22 15:08 被阅读26次

    前言

    kotlin官网 (中文版)和kotlin教程学习教程的笔记。

    一、关于环境配置的建议

    1.建议大家直接用Android Studio3.0+来进行开发,新建项目,勾选support kotlin即可完成相关配置,并进行kotlin的开发。

    1. 比较java和kotlin的区别,使用command+shift+a打开action输入弹窗,输入convert即可将java转换为kotlin。即可看到如下kotlin代码:
    class MainActivity : Activity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
    

    二、类与函数

    1. 类:默认继承Any(类似于Object)。我们写的类只可以继承那些明确声明open或者abstract的类。
    open class Person(name:String,age: Int)
    class Teacher(name: String, age:Int) : Person(name, age)
    
    1. 函数:Kotlin 里没有 void,所有函数都有返回类型
    //返回最大值
    fun maxOf(a: Int, b: Int=0) = if (a > b) a else b
    //可以直接maxOf(1)这样相当于调用maxOf(1,0)
    
    //没有返回值返回Unit,Unit概念上相当于Void,当然也可以不写
       fun showMsg(msg:String){
            println(msg)//在logcat中可看到打印出的内容
        }
    
    1. 覆盖的规则
    open class A {
    open fun f() { print("A") }
     fun a() { print("a") }
    }
    interface B {
    var name: String //属性在接口中不可以被赋值,需要子类重写
    fun f() { print("B") } // 接口的成员默认是 'open' 的 
    fun b() { print("b") }
    }
    class C() : A(), B {
      override var name: String = "c"
    // 编译器要求 f() 方法必须覆盖:
     override fun f() {
    super<A>.f() // 调用 A.f()
    super<B>.f() // 调用 B.f() }
    }
    
    1. 构造函数

    (1). 主构造函数

    class Person(name:String,age:Int){
        init{
            println("My name is $name, I am $age years old ") //相当于构造函数中的内容
        }
    }
    //主构造函数为private
    class Person private  constructor(name:String,age:Int){
    }
    

    (2). 次级构造函数

    class Person( name: String) {
        init {
            println("person init $name")
        }
        constructor(name: String, age: Int) : this(name) {
            println("My name is $name, I am $age years old ") 
        }
    }
        Person("a")
        Person("b", 1)
    
    可以看出执行顺序是构造函数 -> init{}

    三、基本类型与变量

    1. $符号调用表达式
      val & var :val->只读变量,相当于final。var->可变变量。
    val str = "$s.length is ${s.length}" // 计算结果为 "abc.length is 3"
    
    建议自己算一下O(∩_∩)O~:
    1. ?的使用 --进行null检查
     var s:String?=null
      println(s?.length) // s为null输出null, s不为null,输出长度。
    
      fun parseInt(data:String):Int?{ // data不可为null
            return data.toIntOrNull() 
        }
    //----
    fun parseInt(data:String?):Int?{ // data可以为null
            return data?.toIntOrNull() 
        }
    
    val data = ...
    data?.let {
        ... // 这个代码段将在 data 不为 null 时执行
    }
    
    var s: String? = null
    println(s ?: "null string") //输出null string
    val files = File("Test").listFiles()
    println(files?.size ?: "empty") // If not null … else 的简写表达方式
    
    1. 使用is判断类型,相当于instanceOf, 使用as类型转换
     // 在 `&&` 运算符的右侧, `obj` 的类型会被自动转换为 `String`
        if (obj is String && obj.length > 0) {
            return obj.length
        }
    
    (obj as String).length //强制转换
    
    1. 循环
    • while循环不变,for循环有一点变化,如下:
    val items = listOf("a", "b", "c")
    for (item in items) {
            print(item+" ")
    }
    //apple banana kiwi
    
    val items = listOf("apple", "banana", "kiwi")
    for (index in items.indices) {
        println("item at $index is ${items[index]}") //index为下标
    }
    
    • 循环中的返回与跳转:
    loop@ for (i in 1..100) {
        for (j in 1..100) {
            if (...) break@loop
        }
    } //将直接跳出最外层循环
    
      fun loopCheck(){
            (1..10)
                    .forEach list@ { if (it==1) return@list}
            println("touch this")
        } //会输出touch this,如果将list@标签去掉,就不会输入任何内容
    
    return@a 1 //返回到标签 @a 处, 返回值为 1
    
    1. 判断

    (1) when,相当于switch

    val s = when(x){
        is Int -> "Int instance"
        is String -> "String instance"
        else -> throw UnsupportedOperationException("Not valid type") //在Kotlin中, throw 和 try 都是表达式,因此它们可以被赋值给一个变量。
     }
    

    (2) in,相当于contains

    val x = 10
    val y = 9
    if (x in 1..y+1) { //include y+1
        println("fits in range")
    }
    //---------
    if (-1 !in 0..list.lastIndex || list.size !in list.indices) {
        println(" out of range")
    }
    //-----
    for (x in 1..10 step 2) {
        print(x)
    }
    println()
    for (x in 9 downTo -5 step 3) {
        print(x)
    }
    //13579
    //9630-3
    //--------
    for (i in 1 until 10) { ... } //123456789
    for (i in 1.rangeTo(10)   step 2) print(i) //13579
    

    (3) if

    val result = if (param == 1) {"one"} else if (param == 2) { "two"} else { "three"} 
    
    1. 集合collection

    (1) list
    蛮多的,这里不在一一列举,在后续详细讲解

         val food = listOf("orange", "apple", "bear", "tomato")//这种方式只读
            food
                    .filter { it.startsWith("a") }  
                    .sortedBy { it.length }
                    .map { it.toUpperCase() }
                    .forEach { println(it) }
    //APPLE
    //AVOCADO
    

    (2) map

       val map = mapOf("a" to 1, "b" to 3.4, "c" to "sdf")//这种方式只读
            for ((k, v) in map) {
                println("$k->$v")
            }
    
    1. 数组arrays
      var array = arrayOf(1, 2, 3)
      array[0]=array[1]+array[2]
      var array2= doubleArrayOf(1.2,2.3,3.4)
     var array3=Array(5,{i->(i*i).toString()}) //["0", "1", "4", "9", "16"]
    
    1. 字符串String
      1. 原生字符串(raw string)由三重引号表示( """ ), 其内容不转义, 可以包含换行符和任意字符
            val text = """
                   for(c in "foo")
                   print(c)
                   """
            println(text)
    
    三个双引号包裹的字符串 内容 格式不变
         val text = """
                   |for(c in "foo")
                   |print(c)
                   """.trimMargin("|")
            println(text)
    
    删除字符串的前导空白,默认情况下, 会使用 | 作为前导空白的标记前缀
    1. 字符串读取内容
      (1) s.[0]相当于Java中的s.charAt(0)
      (2) for(c in str) 可以读取每个字符
      (3) lazy-延迟计算
    val p: String by lazy {
        // compute the string
    }
    
    1. 位运算
    名称 Kotlin Java
    and &
    or ||
    异或 xor ^
    有符号左位移 shl <<
    有符号右位移 shr >>
    无符号右位移 ushr >>>
    val x = (1 shl 2) and 0x000FF000
    
    1. 相等操作符
    Kotlin Java
    == equals
    != !equals
    === ==
    !== !=

    四、导入import

    import 关键字不仅可以用来导入类; 还可以用来导入其他声明:

    • 顶级(top-level) 函数和属性;
    • 对象声明 中定义的函数和属性;
    • 枚举常数
      那么什么是顶级函数呢?
    package demo
     val name="a"//顶级属性
    fun top(){} //顶级函数
    class Teacher
    

    导入:

    import demo.name as teacherName//可以使用新名称teacherName访问name
    import demo.top
    

    函数, 属性, 类, 对象, 接口, 都可以声明为”顶级的(top-level)”, 也就是说, 直接声明在包之内

    五、修饰符

    • private 表示只在这个类(以及它的所有成员)之内可以访问;
    • protected — 与 private 一样, 另外在子类中也可以访问;
    • internal — 在 本模块之内, 凡是能够访问到这个类的地方, 同时也能访问到这个类的 internal 成员;
    • public — 凡是能够访问到这个类的地方, 同时也能访问这个类的 public 成员.
    open class Outer {
    private val a = 1
     protected val b = 2
     internal val c = 3
    val d = 4 // 默认为 public
    protected class Nested { 
    public val e: Int = 5
    } 
    }
    class Subclass : Outer() {
     // a 不可访问
    // b, c 和 d 可以访问
    // Nested 和 e 可以访问
    }
    class Unrelated(o: Outer) {
    // o.a, o.b 不可访问
    // o.c 和 o.d 可以访问(属于同一模块)
    // Outer.Nested 不可访问, Nested::e 也不可访问
    }
    

    在 Kotlin 中, 外部类(outer class)不能访问其内部类(inner class)的 private 成员

    后记

    1. 有人在操作过程中,可能会看到添加!!的提示
       val c: Int? = null
       println(c!!.toString())
    

    这样写会崩溃KotlinNullPointerException, 因为!! 强制编译器执行null类型时跳过null的检查。

    1. 模块:一个模块(module)是指一起编译的一组 Kotlin 源代码文件:
    • 一个 IntelliJ IDEA 模块;
    • 一个 Maven 工程, 或 Gradle 工程;
    • 通过 Ant 任务的一次调用编译的一组文件

    相关文章

      网友评论

        本文标题:Kotlin for android学习一:基础知识

        本文链接:https://www.haomeiwen.com/subject/nfezsxtx.html