• Kotlin入门学习笔记


    1、java转kotlin:

    打开要转的java文件

      1. 快捷键 Ctrl+Shift+Alt+K 直接转换
      2. 快捷键 Ctrl+Shift+A在搜索框输入Convert Java File to Kotlin或者
      3. Code ->Convert Java File to Kotlin 
      4. 这里写图片描述

    List.add报错:

    使用MutableList代替List,方可使用add方法。

    2、语法:

    2.1 变量

    让我们来看一个很简单的程序。

    fun main(args: Array<String>) {
        var quantity = 5
        val price: Double = 20.3
        val name: String = "大米"
    
        println("单价:$price")
        println("数量:$quantity")
        println("产品:$name 总计:${quantity * price}")
    }

    上面的代码中,首先创建了一个名为quantity的变量用以表示产品的数量,并初始化为 5。

    一个值为 20.3 的常量price,用来表示产品的单价。
    一个表示产品名字的字符串常量name

    通过这段代码我们可以看到,Kotlin 语言声明一个变量使用关键字var,声明一个常量使用val,声明时 Kotlin 语言是可以自动推测出字段类型的,例如上面代码中的var quantity = 5会被认为是Int类型,但如果你希望它是一个Double类型,则需要显示声明类型,例如var quantity: Double = 5

    2.1.2 定义数组

     val names: Array<String> = arrayOf("Kyo", "Ryu", "Iory") 
     val emptyStrings: Array<String?> = arrayOfNulls(10) 

    2.2 语句

    2.2.1 in关键字的使用

    判断一个对象是否在某一个区间内,可以使用in关键字

    //如果存在于区间(1,Y-1),则打印OK
    if (x in 1..y-1) 
      print("OK")
    
    //如果x不存在于array中,则输出Out
    if (x !in 0..array.lastIndex) 
      print("Out")
    
    //打印1到5
    for (x in 1..5) 
      print(x)
    
    //遍历集合(类似于Java中的for(String name : names))
    for (name in names)
      println(name)
    
    //如果names集合中包含text对象则打印yes
    if (text in names)
      print("yes")

    2.2.2 when表达式

    类似于 Java 中的 switch,但是 Kotlin 更加智能,可以自动判断参数的类型并转换为响应的匹配值。

    fun cases(obj: Any) { 
      when (obj) {
        1       -> print("第一项")
        "hello" -> print("这个是字符串hello")
        is Long -> print("这是一个Long类型数据")
        !is String -> print("这不是String类型的数据")
        else    -> print("else类似于Java中的default")
      }
    }

    2.2.3 智能类型推测

    判断一个对象是否为一个类的实例,可以使用is关键字
    与 Java 中的instanceof关键字类似,但在 Kotlin 中如果已经确定了一个对象的类型,可以在接下来的代码块中直接作为这个确定类型使用。

    fun getStringLength(obj: Any): Int? {
      if (obj is String) {
        // 做过类型判断以后,obj会被系统自动转换为String类型
        return obj.length 
      }
    
      //同时还可以使用!is,来取反
      if (obj !is String){
      }
    
      // 代码块外部的obj仍然是Any类型的引用
      return null
    }

    2.2.4 空值检测

    Kotlin 是空指针安全的,也就意味着你不会再看到那恼人的空指针异常。
    例如这句代码 println(files?.size),只会在files不为空时执行。
    以及,你可以这样写

    //当data不为空的时候,执行语句块
    data?.let{
        //... 
    }
    
    //相反的,以下代码当data为空时才会执行
    data?:let{
        //...
    }

    2.3 函数

    2.3.1 函数的声明

    函数使用关键字fun声明,如下代码创建了一个名为say()的函数,它接受一个String类型的参数,并返回一个String类型的值

    fun say(str: String): String {
        return str
    }

    同时,在 Kotlin 中,如果像这种简单的函数,可以简写为

    fun say(str: String): String = str

    如果是返回Int类型(事实上只要是编译器可以推断的类型),那么你甚至连返回类型都可以不写

    fun getIntValue(value: Int) = value

    2.3.2 函数的默认参数

    你也可以使用默认参数来实现重载类似的功能

    fun say(str: String = "hello"): String = str

    这时候你可以调用say(),来得到默认的字符串 "hello",也可以自己传入参数say("world")来得到传入参数值。

    有时参数非常多的时候,也可以使用多行参数的写法,它们是相同的

    fun say(firstName: String = "Tao",
            lastName: String = "Zhang"){
    }

    2.3.3 变参函数

    同 Java 的变长参数一样,Kotlin 也支持变长参数

    //在Java中,我们这么表示一个变长函数
    public boolean hasEmpty(String... strArray){
        for (String str : strArray){
            if ("".equals(str) || str == null)
                return true;
        }
        return false;
    }
    
    //在Kotlin中,使用关键字vararg来表示
    fun hasEmpty(vararg strArray: String?): Boolean{
        for (str in strArray){
            if ("".equals(str) || str == null)
                return true 
        }
        return false
    }

    2.3.4 扩展函数

    你可以给父类添加一个方法,这个方法将可以在所有子类中使用
    例如,在 Android 开发中,我们常常使用这样的扩展函数:

    fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(this, message, duration).show()
    }

    这样,我们就可以在每一个Activity中直接使用toast()函数了。

    2.3.5 将函数作为参数

    Kotlin 中,可以将一个函数作为参数传递给另一个函数

    fun lock<T>(lock: Lock, body: () -> T ) : T {
            lock.lock()
            try {
                return body()
            }
            finally {
                lock.unlock()
            }
    }

    上面的代码中,我们传入了一个无参的 body() 作为 lock() 的参数,

    2.4 小结

    最后,我们用一段代码来总结本章内容,你能看懂吗?

    fun main(args: Array<String>) {
    
        val firstName: String = "Tao"
        val lastName: String? = "Zhang"
    
        println("my name is ${getName(firstName, lastName)}")
    }
    
    fun hasEmpty(vararg strArray: String?): Boolean {
        for (str in strArray) {
            str ?: return true
        }
        return false
    }
    
    fun getName(firstName: String?, lastName: String? = "unknow"): String {
        if (hasEmpty(firstName, lastName)) {
            lastName?.let { return@getName "${checkName(firstName)} $lastName" }
            firstName?.let { return@getName "$firstName ${checkName(lastName)}" }
        }
        return "$firstName $lastName"
    }
    
    fun checkName(name: String?): String = name ?: "unknow"

    4、Kotlin 的类特性

    4.1 构造函数

    Kotlin 的构造函数可以写在类头中,跟在类名后面,如果有注解还需要加上关键字constructor。这种写法声明的构造函数,我们称之为主构造函数。例如我们为Person创建带一个String类型参数的构造函数。

    class Person(private var name: String) {
        fun sayHello() {
            println("hello $name")
        }
    }

    在构造函数中声明的参数,它们默认属于类的公有字段,可以直接使用,如果你不希望别的类访问到这个变量,可以用private修饰。
    在主构造函数中不能有代码实现,如果有额外的代码需要在构造方法中执行,要放到init代码块中执行。

    class Person(private var name: String) {
    
        init {
            name = "Zhang Tao"
        }
    
        internal fun sayHello() {
            println("hello $name")
        }
    }

    4.2 次级构造函数

    一个类当然会有多个构造函数的可能,只有主构造函数可以写在类头中,其他的次级构造函数(Secondary Constructors)就需要写在类体中了。

    class Person(private var name: String) {
    
        private var description: String? = null
    
        init {
            name = "Zhang Tao"
        }
    
        constructor(name: String, description: String) : this(name) {
            this.description = description
        }
    
        internal fun sayHello() {
            println("hello $name")
        }
    }

    这里我们让次级构造函数调用了主构造函数,完成 name 的赋值。由于次级构造函数不能直接将参数转换为字段,所以需要手动声明一个 description 字段,并为 description 字段赋值。

    4.3 修饰符

    4.3.1 open 修饰符

    Kotlin 默认会为每个变量和方法添加 final 修饰符。这么做的目的是为了程序运行的性能,为每个类加了final也就是说,在 Kotlin 中默认每个类都是不可被继承的。如果你确定这个类是会被继承的,那么你需要给这个类添加 open 修饰符。

    4.3.2 internal 修饰符

    写过 Java 的同学一定知道,Java 有三种访问修饰符,public/private/protected,还有一个默认的包级别访问权限没有修饰符。
    在 Kotlin 中,默认的访问权限是 public,也就是说不加访问权限修饰符的就是 public 的。而多增加了一种访问修饰符叫 internal。它是模块级别的访问权限。
    何为模块(module),我们称被一起编译的一系列 Kotlin 文件为一个模块。在 IDEA 中可以很明确的看到一个 module 就是一个模块,当跨 module 的时候就无法访问另一个module 的 internal 变量或方法。

  • 相关阅读:
    从员工到总监,我的7个经验心得(转)
    对上司不满,说还是不说
    老子智慧-大道甚夷
    实际操作中命令 su 与 sudo 的区别(转)
    杨氏矩阵查找元素位置Java实现
    Java实现 蓝桥杯 算法提高 周期字串
    Java实现 蓝桥杯 算法提高 周期字串
    Java实现 蓝桥杯 算法提高 学霸的迷宫
    Java实现 蓝桥杯 算法训练 最大最小公倍数
    Java实现 蓝桥杯 算法训练 最大最小公倍数
  • 原文地址:https://www.cnblogs.com/Jackie-zhang/p/9638841.html
Copyright © 2020-2023  润新知