Kotlin基础
类型系统、setter和getter、构造器等
is 判断类型 (相当于java的instanceof )
as 强转类型 (相当于java的 (Type))
在kotlin中获取class对象,LessonActivity::class 获取的是kotlin对象,LessonActivity::class.java获取的是java的对象
set和get,如下注释代码是默认的不需要写的(使用了var关键字),如果set和get有特殊逻辑才需要写
但是怎么把set设置为私有、外部调用不了呢?如下:在java中直接访问kotlin的成员变量,可以在kotlin变量中加@JvmField,生成就是一个公开的,并且没有set和get方法。
java基类是Object,kotlin是Any,同时Any没有wait、notify等方法
kotlin继承类的时候,并不一定要加(), 只要有写一个构造函数就可以不写()
openclassPerson{}// 这里Person后面不用()classUser:Person{constructor()}- arrayOf方法来声明基本类型的数组,比如int会有拆装箱性能问题,此时可以用intArrayOf解决,其他基本类型类似
静态函数、注解、单例
1.顶层(包级)函数或属性: 直接把函数或者属性定义在文件中。(其实会被编译这个文件的静态函数和属性)
2.对象声明 object className ,作用是单例,kotlin可以直接通过类名调用,java都是通过实例调用
3.伴生对象companion object, 也是一个单例对象,kotlin可以直接通过类名调用,java都是通过实例调用
4.object: className {}, 匿名内部类
5.区间可以使用in表示,比如 code in 200…299 是一个闭区间
6.when相当于java的switch关键字的作用,但是when的分支支持表达式,而不仅仅字段值.。另外when是可以有返回值的
internal、enum
1.枚举enum class className, 这里需要两个关键字
enumclassState{PLAY{overridefunstateName():String{return"1"}},PAUSE{overridefunstateName():String{return"2"}};// 抽象方法,需要枚举实例自实现abstractfunstateName():String}2.java通过MainActivity.this, 这里this来获取外部的对象的,kotlin则是通过this@MainActivity
3.List是不可修改的数组,如果要修改可以用arrayListOf 或者mutableList
vallist=mutableListOf<Int>()4.java默认是内部类是嵌套内部类,除非显示声明static才是静态内部类。
5.kotlin默认是静态内部类,如果是要嵌套内部类,则需要声明inner class
6.internal关键字,表示当前模块可用,外部模块不可用。比如开发的sdk内部可用,但是不希望暴露出去(java做不到,只能声明为public),internal还可以用在方法、属性等
7.普通类默认是final的,如果要可以被继承需要加open或者abstract
构造、数据类及反编译
主构造函数:写在类名处,以及内部使用init初始化
还可以简化成:通过var 字段,变成了一个成员属性
从构造函数的声明需要调用主构造函数,如下
classTestClassconstructor(varuserName:String?=null){// 调用主构造函数constructor():this("test"){}}数据类:data class
数据类会有copy、equals(等同于==)、hashCode等方法
注意:==是对比值、 ===是强制比较地址值,即是否同个对象
另外如下示例,返回的是数据类可以用val () 来表示
操作符、循环、中缀表示法
通过:?设置默认值
遍历:
数组遍历,红框2可以替代红框1,在lambda中,由于只有一个参数,所以可以不写,直接有it表示唯一的参数
另外可以由filter实现
循环:
repeat函数
for(i in 0…200) 左右闭区间
for(i in 0 until array.size) 左必右开
嵌套函数、函数简化、参数默认值、扩展函数
嵌套函数
函数简化:因为函数只有一行,可以省略返回类型,并且用等号。如果函数没有返回值,也是同样写法
参数默认值:可以应对方法重载过多的问题,可以设置默认值的话就可以简化成一个方法
扩展函数: 这里通过Float.对浮点数声明扩展函数,里面使用this表示浮点值。
如果对已有的系统方法,写相同扩展是无效的。
通过反编译可以知道:扩展函数 其实 就是静态方法,方法参数之一就是被扩展对象
扩展属性:
inline、函数类型、reified
inline内联函数:就是把函数的实现拷贝到调用的地方。意义可以减少一层调用栈,但是也增加了编译时间。
函数类型:
listener是参数名,后面表示是一个函数类型,这里有到->箭头,后面跟着是返回类型
还可以再简化:去掉view字段名
内联函数被推荐使用在参数是函数类型的时候,通过反编译可以看到这种情况使用非内联函数的话,每次都会创建一个对象,频繁调用有性能损耗。内联的话则是直接拷贝代码过去,没有这个问题。
reified的是用:
最初的调用:
通过inline + reified的可以拿到T的类型,这里inline帮助直接使用泛型
by关键字原理 (委托)
首次调用,才是执行到lazy的lambda。
另外by还可以如下委托,减少重复代码,即可以复用代码
还支持传参
作用域函数
apply、let、with、also、run、
区别:返回类型不同、作用域内部是使用this,还是it
let:最后一行是返回值,这里还需要手动返回itapply:不需要手动返回,因为默认返回的是this
意义:通过作用域函数可以分割代码,把相同逻辑都写在同一个作用域,不然我们平常写代码都是用空行来分割下。
