kotlin入门学习笔记

《极客时间---快速上手Kotlin开发》学习笔记(一)

2019-11-19  本文已影响0人  青_雉

kotlin 学习笔记(一)

笔记整理至极客时间《快速上手kotlin开发》,本文整理至1~10集系列视频。

变量声明

//var <变量名> 类型 = ...  
//结尾不需要分号
var name: String = "zhangsan"

//也可以利用类型自动判断,省去类型
var name = "zhangsan"

函数

//函数写法和golang有点像,返回值在入参列表的后面
//入参: name
//返回值: String 类型
//字符串拼接不需要像java里一样的String.format("hello %s", name), 和shell脚本一样,比较方便
fun sayHello(name: String): String {
  return "hello $name"
}

类扩展

扩展函数

假设有自定义类在文件TeacherService.kt

class TeacherService(private val student: Student) {
    fun sHello() {
        student.hello()
    }
}

下面针对这个类进行扩展 e.kt

public fun TeacherService.getStudentName():String  = "hello"

public fun TeacherService.fuza(name: String = "haha"):String {
    return name
}

可进行如下测试

var ts = TeacherService(Student())
ts.sHello()

println(ts.getStudentName())
println(ts.fuza())

下面针对jdk标准类库进行扩展

fun <T> Collection<T>.joinToString(
        separator: String = ",",
        prefix: String = "",
        postfix: String = ""
): String{
    val result = StringBuilder(prefix)
    for ((index, value) in this.withIndex()) {
        if (index > 0) {
            result.append(separator)
        }
        result.append(value)
    }
    result.append(postfix)
    return result.toString()
}

测试

println(listOf("a", "b", "c").joinToString(prefix = "[", postfix = "]"))

kotlin里,针对jdk的许多标准库进行了函数扩展,比如 FileReadWrite.kt

当然扩展函数,只是相当于在扩展类里面添加的静态方法,如果用java代码进行调用,就没什么黑魔法了

TeacherService ts = new TeacherService(new Student());
ts.sHello();
EKt.getStudentName(ts);
扩展属性

相关文档里讲,属性也是可以扩展的,但是研究了一下,有一点不明白属性扩展能做啥

var String.s: Int
get() = this.length
set(value){
  //set方法并没有field可以用来存储value,
  //其实际作用是使用通过value来操作调用者,即this
  println(this.plus(value))
}

Lambda 闭包

var hello = {s: String -> println(s)}
fun main(args: Array<String>) {
    hello("hah")
}

最基本的lambda写法

fun main(args: Array<String>) {
    val thread = Thread({ -> Unit })
    thread.start()
}

如果没有参数,可以省略箭头符号 ->

fun main(args: Array<String>) {
    val thread = Thread({ })
    thread.start()
}

如果lambda是函数的最后一个参数,可以将大括号放在小括号外部

fun main(args: Array<String>) {
    val thread = Thread(){}
    thread.start()
}

如果函数只有一个参数切这个参数是lambda,可以省略小括号

fun main(args: Array<String>) {
    val thread = Thread{}
    thread.start()
}

为什么在lambda上玩出这么多花头精?因为想支持函数式编程,必须要简洁,java原生的匿名内部类写法太过臃肿,java8之后出的lambda有一些改善,kotlin在此基础上进行更加好的改善。

为什么要匿名内部类?主要在两个领域会经常用到匿名内部类

java或者说jvm体系,没有函数的概念,只有方法, 想要支持函数式编程,jvm体系上,基本上是基于匿名内部类来实现的,kotlin里在kotlin.jvm.functions包里内置了很多的Function接口,无非是让人感觉是在写函数。

高阶函数

传入函数

把函数传给函数(jvm层面,无非是把一个对象传给一个函数,实现一种回调的效果)

fun main(args: Array<String>) {
    onlyif(true) {
        println("ddd")
    }
}

fun onlyif(isDebug: Boolean, block: () -> Unit){
    if(isDebug) block()
}

所以,如果大量使用高阶函数,就会造成大量的临时对象产生(没有追求性能极致,貌似也没什么问题),所以kotlin里发明了inline 关键字。

返回函数

(想起了早些年写的js,记得js里为了实现某一种封装,是通过返回一个函数来实现的)

fun main(args: Array<String>) {
    println(doSth()())
}

fun doSth(): () -> String {
    var name = "xiaoming"
    return {name}
}

构造函数

定义父类和接口

//open 的类才能被继承
open class Person {
    //open的方法才能被覆盖
    open fun sayHi(){
        println("hello")
    }
}

interface Runer {
    fun run()
}

实现父类和接口

class Student(var name: String) : Person(), Runer {
    //构造函数执行的时候,init代码块里的代码将被执行(不管是主构造函数还是次级构造函数)
    init {
        println(name)
    }

    //主构造函数的name,不需要额外声明;次级构造函数的参数需要额外声明
    var age: Int = 0

    /**
     * 次级构造函数必须直接或间接的继承主构造函数或父级构造函数
     */
    constructor(name: String, age: Int) : this(name) {
        this.age = age
    }

    //覆盖父类的方法,必须带override关键字
    override fun sayHi() {
        println("hi I'm $name, I'm $age years old")
    }

    override fun run() {
//        TODO("not implemented") 这个TODO是可以编译通过的,运行时报错
        println("student run")
    }
}

伴生对象

静态工具类

//通过伴生对象来做
class StringUtils {
    companion object {
        fun isEmpty(str: String) : Boolean {
            return "" == str
        }
    }
}

//通过jvmStatic注解来做
object XXUtils {
    @JvmStatic
    fun isBlank(str: String) : Boolean {
        return "" == str
    }
}

fun main(args: Array<String>) {
    println(StringUtils.isEmpty(""))
    println(XXUtils.isBlank("abc"))
}

单例

class Student private constructor() {

    companion object {
        fun get() :Student {
            return Holder.instance
        }
    }

    private object Holder {
        var instance: Student = Student()
    }

}

fun main(args: Array<String>) {
    println(Student.get())
    println(Student.get())
}

关于object的修饰符

参考文档

https://www.jianshu.com/p/7291c9a1ec1e

上一篇 下一篇

猜你喜欢

热点阅读