Kotlin基础
intellid IDE查看函数注释
3
1
按一下 shift + q 显示提示框
2
3
连按两下 shift +q 显示新的窗口
使用Itellij IDE显示kotlin字节码,连续按两次shift

包名
x
1
package cn.rxdidi
2
3
// 导入包
4
import cd.rxdidi
常量
x
1
const val a = "123":
2
3
fun mian()
4
{
5
println("编译时常量只能在函数外申明")
6
}
变量
x
1
var a;// 可以重复赋值
2
val b; // 只能赋值一次,相当于常量
3
4
var a :int = 1; // int类型的变量
5
6
// 多行文本,.trimIndent()除去空格字符
7
var str = """
8
adf
9
asdf
10
asdf
11
asdf
12
asdf
13
""".trimIndent()
14
println(str)
15
16
// val str = "字符串模板";
17
println("类似C#的语法,$str")

数组
x
1
fun Aarr(){
2
// 创建一个一维数组
3
var arr = Array(5){i->i*5}
4
// 循环输出数组,it = item
5
arr.forEach { println(it) }
6
7
// 创建一维数组数组
8
var arr2 = arrayOf(1,2,3,4,5)
9
10
arr2.forEach { println(it) }
11
12
// 一维数组
13
arrayOf("1","2","3")
14
println("一维数组,字符串")
15
var ArrStr = Array(5){""}
16
ArrStr[0] = "0";
17
ArrStr[1] = "1";
18
ArrStr[2] = "2";
19
ArrStr[3] = "3";
20
ArrStr[4] = "4";
21
for (i in ArrStr) println(i)
22
// 创建数组
23
24
var arr3 = IntArray(5){6}
25
arr3[1] = 34;
26
println("arr3-1 = "+arr3[1])
27
arr3.forEach { println(it) }
28
29
// 访问数组
30
31
val arr3_3 = arr3.get(1)
32
println("使用get访问数组: " + arr3_3)
33
34
// 设置数组
35
arr3.set(2,53)
36
val arr3_2 = arr3.get(2)
37
println("使用set访问数组: " +arr3_2)
38
39
val str = "字符串模板";
40
println("类似C#的语法,$str")
41
42
// 多维数组
43
println("多维数组")
44
val arrList = Array<Array<String>>(2){Array<String>(2){""} }
45
val arrList2 = Array(2){Array(2){""} }
46
arrList2[0][0] = "一";
47
arrList2[0][1] = "二";
48
arrList2[1][0] = "一一";
49
arrList2[1][1] = "一二";
50
for ((value,item) in arrList2.withIndex())
51
{
52
53
for (j in item.indices){
54
println(arrList2[value][j])
55
}
56
}
57
58
59
// 多维数组
60
val arrArr = Array(2){Array<String>(2,{""}) }
61
arrArr[0][0] = "10";
62
arrArr[0][1] = "20";
63
arrArr[1][0] = "30";
64
arrArr[1][1] = "40";
65
66
var i = 0;
67
var j = 0;
68
for (item in arrArr){
69
for ( itms in item[i]){
70
71
72
println(arrArr[i][j])
73
74
j++;
75
}
76
i++;
77
j=0;
78
}
79
80
// 3维数组
81
var arrArrArr = Array<Array<Array<String>>>(3){Array<Array<String>>(3){Array<String>(3){""} }}
82
83
// 3维数组
84
var arrArr2 = Array(3){Array(3){Array<String>(3,{""})} }
85
86
}
ForWhenWhlieIf
x
1
fun ForWhenWhileIf(){
2
// 等同于 0 <= i && i <= 3
3
for (item in 0..3) println(item)
4
// for循环数组, 相当于C#的foreach
5
var arr = arrayOf(1,2,3,4,5,6);
6
for (item in arr) println(item)
7
8
// 区间表达downTo , 相当于: 10 = 3 结束本次递送;
9
println("区间表达downTo")
10
for (item in 10 downTo 3) println(item)
11
12
// 区间表达 step, 每循环一次跳过4次,如果step = 1说明不跳过循环, = 0 则崩溃
13
println("区间表达 step, 每循环一次跳过4次")
14
for (item in 1..10 step 4) println(item)
15
16
// 这条语句=
17
println("区间表达式,反向递送 downTo 说明: i = 6 , i == 3 break")
18
println("反向循环,循环6次,第三次结束,每循环一次跳过2此")
19
for (i in 6 downTo 3 step 2) {
20
println(i)
21
}
22
23
// for 使用(item,value) 等同于c#的foreach
24
println("for 使用(item,value) 等同于c#的foreach")
25
var arr2 = arrayOf(50,40,30,20,10)
26
for((value,item) in arr2.withIndex())
27
{
28
println(value)
29
println(item)
30
}
31
32
// for使用循环,item值为循环次数
33
println("for使用循环,item值为循环次数")
34
for (item in arr2.indices)
35
{
36
println(arr2[item])
37
}
38
39
// if语句用法
40
println("if语句作为表达式")
41
val a = 1;
42
val b = 2;
43
var ifLarge = if(a>b)b else a;
44
45
println(ifLarge)
46
47
// 正常的if语句
48
var max:Int;
49
if(a > b)
50
{
51
max = a;
52
}else{
53
max = b;
54
}
55
56
// when语句, 等同于其他语言的switch,但是when的用处更多
57
println("when语句")
58
var whenVal = "ok"
59
when(whenVal){
60
"ok" -> println("whenVal = ok")
61
"no" -> println("whenVal = no")
62
else -> println("whenVal = null") // else为默认值
63
}
64
65
// when, 相当于其他语言的
66
/*
67
* case 1:
68
* case 2;
69
*
70
* break;
71
* */
72
var whenVal2 = 0;
73
when(whenVal2){
74
1,2 -> println("whenVal2 = 1 or 2")
75
else ->{
76
println("whenVal2 = null")
77
}
78
}
79
80
// when 检测一个值 is 或 !is 一个特定的值
81
// 下面这个表示:如果字符串以prefix开头返回true否则false
82
83
fun hasprefix(x:Any) = when(x){
84
is String -> x.startsWith("prefix") // 如果字符串包含prefix开头则返回true
85
is Int -> true // 如果是int类型返回true
86
else -> false
87
}
88
89
var istrue = hasprefix("prefix is true")
90
println(istrue)
91
var istrue2 = hasprefix(2)
92
println(istrue)
93
}
range表达式,表示 几到几之间, 0 .. 10 or 1..3 = 0到10之间 或 1到3之间
23
1
val a = 3;
2
3
if(a in 0 .. 3)
4
{
5
println("他在0到3之间")
6
}
7
8
if(a !in 0..3)
9
{
10
println("他不在0到3之间")
11
}
12
13
// downTo
14
15
for(item in 10 down 1) println(" 反向递送 = 10 9 8 7 .. 1 ");
16
17
// step
18
for (item in 10 step 2) println("每循环一次跳过两次");
19
20
// until
21
22
for(item in 1 until 10) prinln("i in [1, 10), 10被排除")
23

when表达式,满足某个条件后执行相应代码
7
1
val a = "ok";
2
3
when(a)
4
{
5
"ok" -> println("a = ok")
6
else -> println("a 等于啥我也不知道啊")
7
}
StringTemplate 字符串模板
11
1
val a = "我是变量a";
2
val b = "我是变量b";
3
var S = "字符串模板可以使用变量和表达式: 变量a =$a 变量b = $b ";
4
5
println(S)
6
7
println("同时StringTemplate还可以使用表达式")
8
9
val isTrue = false;
10
val S2 = "判断一个值是否为true : ${if(isTrue) " = true" else " = false"}";
11
println(S2)
函数

5
1
// age 默认值 = 18
2
// FunctionParpam返回值为空,Unit = C#语言的void
3
private fun FunctionParpam(age :Int = 18, name :String):Unit{
4
5
}
TODO抛出异常,终止代码运行
5
1
private fun FunctionParpam(age :Int = 18, name :String):Unit{
2
3
// 使用ToDo函数可以抛出异常,终止代码运行
4
// ToDo("错误原因")
5
}
反引号申明 特殊字符方法
· 这个符号在tab键上面

x
1
fun `我是反引号方法`(){
2
println("反引号申明特殊字符方法")
3
println("反引号申明特殊字符方法")
4
}
匿名函数
x
1
fun `匿名函数`(){
2
// 匿名函数使用方法就是C#的lambad
3
4
var Anonymous = "用匿名函数判断此字符串重复的字符串数量".count({string -> string == '字'})
5
6
println(Anonymous)
7
8
}

匿名函数隐式返回
15
1
fun `匿名函数隐式返回`(){
2
3
// 匿名函数声明方法一
4
val BlessingFunction1:()-> String = {
5
"隐式返回默认返回最后一行,无需return"
6
}
7
8
// 匿名函数隐式返回2
9
val BlessingFunction2:() -> String
10
11
BlessingFunction2 = {
12
"隐式返回默认返回最后一行,无需return"
13
}
14
}
15
匿名函数只有一个参数时,可以用it代替
8
1
fun `匿名函数只有一个参数时`(){
2
var AnonymousIt:(Str:String)->String = {
3
it->
4
"匿名函数只有一个参数时,可以用it代替:{$it}"
5
}
6
7
println(AnonymousIt("我是匿名函数的参数,当匿名函数只有一个参数时可以用it代替"))
8
}
匿名函数类型推断,大大减少代码量
x
1
var BlessingFunction = {
2
"当匿名函数没有参数时,简略写法可以这么写"
3
}
4
5
var blessingFunction2 = {
6
Str:String,int:Int->
7
"当匿名函数有参数时,简略写法:参数一 = $Str, 参数二 = $int"
8
}
匿名函数就是Lambda#
11
1
kotlin的Lambda
2
3
()-> String {
4
Param:String ->
5
"我是kotlin的lambda函数,参数一调用:$Param"
6
}
7
8
C#的Lambda
9
10
Func<参数 Param, string 返回值>= a => $"Lambda参数一的值为: {a}";
11
当函数参数是lambda时
30
1
fun `当Lambda被当作参数时`(){
2
3
var Lambda:(String) -> String = {
4
it ->
5
it // 返回it , it = 默认参数
6
}
7
8
// 调用函数,函数内含有Lambda
9
// 使用此方法调用,感觉非常麻烦
10
11
println("使用常规方法调用函数")
12
val a = FunLambda(18,Lambda)
13
14
// 调用函数,函数内含有Lambda
15
// 括号里面写函数的参数,大括号里面就是Lambda
16
17
println("使用简略方法调用函数")
18
val b= FunLambda(18){
19
it // 返回it , it = 默认参数
20
}
21
22
23
24
25
26
}
27
28
fun FunLambda(age : Int, Name:(String)->String){
29
println("年龄 = $age , 姓名 = ${Name("匿名函数当参数")}")
30
}

内联函数 inline
7
1
// 自己认为:
2
// 内联函数:重复、多次使用同一个函数可以使用内联函数来减少损耗
3
4
inline fun InlineFun()
5
{
6
println("当一个函数被多次调用时,可以使用inline来减少服务器压力")
7
}
函数处理可以用lambda作为参数之外还可以使用函数做为参数,使用 :: + 函数名即可
14
1
fun `函数除了可以调用Lambda以外还可以直接调用函数`(){
2
3
// 函数除了可以用lambda作参数之外,还可以用函数做参数,使用 :: + 函数名
4
5
FunLambda(18,::Name)
6
}
7
8
fun Name(Str:String):String{
9
return Str;
10
}
11
12
fun FunLambda(age : Int, Name:(String)->String){
13
println("年龄 = $age , 姓名 = ${Name("匿名函数当参数")}")
14
}
当返回类型为Lambda时
12
1
// 声明
2
3
fun `返回类型是Lambda时`():(String)->String {
4
return {
5
"返回类型为 Lambda时,参数一的值为: $it"
6
}
7
}
8
9
// 调用
10
11
val WriteLambda = 返回类型是Lambda时()
12
println(WriteLambda("我是参数一的值"))
可空类型,var str:String? = "";
1
1
var str:String? = "可空类型";
安全调用操作符
5
1
var str:String? = "可空类型";
2
str = null;
3
4
//可空类型必须使用?,否则会报错
5
str?.trim();
可空类型使用let函数
19
1
// 可空字符串使用 let函数
2
fun nullLet(){
3
4
var str:String? = "本字符串可以为空"
5
str = null
6
7
// 使用let函数
8
str = str?.let{
9
it:String->
10
11
if(it.length > 5){
12
"大于5"
13
}else{
14
"小于5"
15
}
16
}
17
18
println(str)
19
}
非空运算符,!!.
7
1
// 非空运算符,如果为空发出异常
2
fun noNull(){
3
var str:String? = "非空运算符,如果为空发出异常";
4
5
6
println(str!!.length);
7
}
合并操作符,相当于C#的三元表达式 ? :
10
1
// 空合并操作符 ?:
2
fun `空合并操作符`(){
3
4
var str:String? = "空合并操作符";
5
6
str = null
7
// 不为空为左,为空为右
8
9
println(str?.let { it.capitalize() } ?: "str is null")
10
}
自定义异常,继承exception
20
1
// 自定义异常
2
fun `自定义异常`(){
3
4
var str:String? = null;
5
6
try {
7
// 触发异常
8
throw customException();
9
// 如str不为空则str +1
10
str!!.plus("+1");
11
12
}catch (e:Exception){
13
println(e)
14
}
15
16
17
}
18
19
// 自定义异常,继承Exception
20
class customException() : Exception("为空")
检测参数是否为空,如果为空发出自定义异常
7
1
// 检测参数不为空,如果为空返回自定义异常
2
fun `检测参数不为空`(){
3
var str:String? = null;
4
5
checkNotNull(str,{"参数为空"})
6
7
}

解构语法,把list赋值给变量
14
1
// 解构语法
2
fun `解构语法`(){
3
4
var str = "a,b,c";
5
var strList = str.split(',')
6
7
// 常规调用方式
8
//println(strList[0])
9
10
// 解构语法, 把list赋值给变量
11
var (str1,str2,str3) = strList
12
13
println(str1)
14
}
replace(字符串替换) + regex(正则表达式)
1
// replace
2
fun replaceA(){
3
var str = "a b c d e f g";
4
5
6
var str2 = str.replace(regex = Regex("[^abg]")){
7
when(it.value){
8
"c" -> "1"
9
"d"->"2"
10
"e"->"3"
11
else -> it.value
12
}
13
}
14
15
println(str)
16
17
println(str2)
18
}
== and ===
12
1
// == and ===
2
fun `==and===`(){
3
var str1 = "String";
4
// 将字符串首字母改为大写
5
var str2 = "string".capitalize();
6
7
// = true
8
println(str1 == str2)
9
10
// = false
11
println(str2 === str1)
12
}
字符串遍历
3
1
"字符串遍历".forEach{
2
println(it);
3
}
数字转换
18
1
// 数字转换
2
fun `数字转换`(){
3
// 如果转换失败则为空
4
var a :Int? = "9.9".toIntOrNull()
5
6
// = 9 ,但四舍五入之后为10
7
var b = 9.9.roundToInt();
8
9
// 格式化字符串
10
11
var c = "%.2f".format(3.14125);
12
13
println(a)
14
15
println(b)
16
17
println(c)
18
}
apply函数,在apply里面调用类的方法时无需使用变量名

let and apply
34
1
// let 与 apply对比
2
// let 传入前者结果为参数且返回结果为最后一行
3
// apply 不传入参数,执行结果赋值给变量
4
fun letAndApply(){
5
// let 使用
6
var str = listOf(1,2,3).last().let{
7
it * it
8
}
9
println(str)
10
11
// let + :? 代替if else
12
println(formatGreeting(null));
13
println(formatGreeting("Ddcheat"));
14
15
// apply前后对比
16
17
File("C:\\kotlin.txt").apply{
18
setReadable(true)
19
setWritable(true)
20
setExecutable(false)
21
}
22
23
var createFile = File("C:\\kotlin2.txt")
24
createFile.setExecutable(false)
25
createFile.setReadable(true)
26
createFile.setWritable(true)
27
}
28
29
// 使用let + :? 代替 if else
30
fun formatGreeting(name:String?) : String? {
31
return name?.let {
32
"welcome $it"
33
} ?: "what`s your name"
34
}
run函数
30
1
// run 函数 run 和 apply相比 run接收上一个对象,返回结果为最后一行
2
fun runandApply(){
3
4
var file = File("C:\\Users\\29663\\Desktop\\服务器.txt")
5
6
// run和apply, apply是配置函数, run 是返回函数
7
var result = file.run{
8
readText()
9
}
10
11
println(result)
12
13
// run 还可以使用 引用函数
14
// 可以使用多个run
15
16
var resultLength = result.run(::textISlength)
17
?.run(::textLengthGreaterThan)
18
19
println(resultLength)
20
21
}
22
23
fun textISlength(text:String?) = text?.length
24
fun textLengthGreaterThan(length:Int): String{
25
return if(length > 5){
26
"string Greater Than 5"
27
}else{
28
"String less Than 5"
29
}
30
}
with and run
15
1
// with 跟 run 相似, 但 with 需要传入参数
2
fun withAndrun(){
3
var a = "判断字符串长度".run{
4
length
5
}
6
7
var b = with("判断字符串长度"){
8
length
9
}
10
11
println(a)
12
println(b)
13
14
15
}
also
1
// also 跟 let 函数相似, also 接收对象,返回接受的对象, let 接收对象,返回lambda
2
fun alsoAndlet(){
3
var file = File("C:\\Users\\29663\\Desktop\\服务器.txt").also{
4
println("文件名 = " + it.name)
5
}.also{
6
println(it.readText())
7
}
8
9
}
takeif

8
1
// takeif
2
fun takeif(){
3
var text = File("C:\\Users\\29663\\Desktop\\服务器.txt").takeIf {
4
it.canRead() && it.exists()
5
}?.readText()
6
7
println(text)
8
}
takeUnless , 是takeif的辅助函数,takeif为真时返回对象,而takeunless为假时返回对象
11
1
// takeUnless 当判定条件为假时返回对像,为真时返回null
2
fun takeunless(){
3
// 如果 isHidden为假则执行后面的函数,如果为真则返回null
4
var text:String? = File("C:\\Users\\29663\\Desktop\\服务器.txt").takeUnless{
5
it.exists()
6
}?.let{
7
"这个文件不存在"
8
}
9
10
println(text)
11
}
list集合
10
1
// list
2
fun list(){
3
var strlist :List<String> = listOf("a","b","c")
4
5
// 访问指定索引,如果不存在则为自定义值,Unknown
6
println(strlist.getOrElse(3){"Unknown"})
7
8
// 访问指定索引值,如果为空,则 = Unknown
9
println(strlist.getOrNull(4) ?: "Unknown")
10
}
mutableLIst
17
1
// mutableList 可变集合, list为不可变集合
2
fun mutablelist(){
3
var mutablelist = mutableListOf("a","b","c")
4
// 添加
5
mutablelist.add(3,"d")
6
mutablelist.add("e")
7
// 删除
8
mutablelist.remove("e")
9
10
println(mutablelist)
11
12
// mutablelist 为可变集合, listof为不可变集合
13
// 可变集合 不可变集合可以互转
14
mutableListOf("a","b","c").toList()
15
listOf("a","b","c").toMutableList()
16
17
}
mutator
17
1
// mutator
2
fun mutator(){
3
// 需要使用val 使用var会报错
4
val mutablelist = mutableListOf("a","b","c")
5
// 添加元素
6
mutablelist += "d";
7
// 删除元素
8
mutablelist -= "a"
9
10
// lambda删除元素
11
mutablelist.removeIf{
12
it.contains("b")
13
}
14
15
println(mutablelist)
16
}
17
遍历列表
21
1
// foreach list
2
fun foreachList(){
3
val mutablelist = mutableListOf("a","b","c")
4
5
// 第一种方式
6
for (s in mutablelist) {
7
println(s)
8
}
9
10
// 第二种方式
11
mutablelist.forEach {
12
println(it)
13
}
14
15
// 第三种方式
16
mutablelist.forEachIndexed{
17
index,item->
18
println("$index , $item")
19
}
20
21
}
解构语法忽略赋值
9
1
fun `解构语法忽略赋值`(){
2
val list = listOf("a","b","c")
3
4
// 使用下划线忽略对b的赋值
5
val (a,_,b) = list
6
7
println(a)
8
println(b)
9
}
SetList 不可变Set集合
5
1
// setList 和list 的区别在, setList不可以有重复元素而 list可以有重复元素
2
fun setlist(){
3
val setlist = setOf("a","b","c")
4
println(setlist.elementAt(1))
5
}
MutableSetList 可变Set集合
14
1
// 可变的Setlist
2
fun mutableSetList(){
3
val mutableSetlist = mutableSetOf("a","b","c")
4
5
// 添加或删除元素
6
mutableSetlist.add("d")
7
mutableSetlist.removeIf{it.contains("a")}
8
9
// 添加或删除元素
10
mutableSetlist += "e"
11
mutableSetlist -= "b";
12
13
println(mutableSetlist)
14
}
集合转换, 快捷函数
15
1
// 集合转换 和 快捷函数
2
fun listTOset(){
3
val list = listOf("a","a","b")
4
5
// 去重复元素,但很麻烦
6
val list1 = list.toSet().toList()
7
8
// 去重复元素函数 distinct
9
val list2 = list.distinct();
10
11
println(list)
12
println(list1)
13
println(list2)
14
15
}
mapList
29
1
// mapList key value模式
2
fun mapList(){
3
// 第一种创建方式
4
val maplist1 = mapOf("a" to 10,"b" to 20 ,"c" to 30)
5
6
// 第二种创建方式
7
val maplist2 = mapOf(Pair("a",10),Pair("b",20),Pair("c",30))
8
9
// 索引取值
10
println(maplist1[0])
11
12
// 取值
13
println(maplist2.getValue("a"))
14
println(maplist2.getOrElse("d"){"unknown"})
15
16
// 递送
17
maplist1.forEach { key, value ->
18
println("$key, $value")
19
}
20
// 递送二
21
maplist2.forEach {
22
println("${it.key}, ${it.value}")
23
}
24
// 递送三
25
for (entry in maplist2) {
26
println("${entry.key}, ${entry.value}")
27
}
28
29
}
field , 类属性自定义get / set时使用
8
1
class FirstClass {
2
var str = "capitalize"
3
get() = field.capitalize()
4
set(value) {
5
field = value.trim()
6
}
7
8
}
面向对象
67
1
// 构造函数
2
class ConstructorClass constructor(name:String , age:Int) {
3
4
}
5
6
// 构造函数,无需constructor
7
8
class ConstructorClassTwo (name:String, age:Int){
9
10
}
11
12
// 使用Init初始化代码
13
class InitClass(var name:String){
14
15
init {
16
// 使用also输入此字符串
17
"name = ${name}".also(::println)
18
}
19
20
}
21
22
// 继承类 , 使用open关键字,其变量或方法可以被继承同样使用open
23
open class parentClass(_name:String, _age:Int){
24
// 子类不能重写父类的 var ,比如把var 覆盖为 val
25
open var name = "";
26
open var age = 0;
27
28
init {
29
name = _name;
30
age = _age
31
}
32
33
open fun writeLine() :String{
34
return "年龄 = ${age} , 姓名= ${name}"
35
}
36
}
37
38
// 子类, 使用override
39
40
class sunClass(override var age:Int,override var name:String) : parentClass(_age = age,_name = name){
41
// 继承后,使用super()初始化父类
42
//constructor():super();
43
44
override fun writeLine():String {
45
return "override返回 年龄 = ${age} , 姓名= ${name}"
46
}
47
48
// 如果要调用父类的属性或方法可以使用super
49
fun writeline(){
50
// 调用父类方法
51
super.writeLine().also(::println)
52
// 如果继承多个类或interface 可以这么调用
53
super<parentClass>.writeLine().also(::println)
54
// 调用父类属性
55
println("父类中age = ${super.age}")
56
}
57
}
58
59
// 抽象类
60
abstract class AbstractClass:parentClass{
61
// 给父类属性赋值
62
constructor(age: Int,name: String):super(name, age);
63
64
override fun writeLine(): String {
65
return super.writeLine()
66
}
67
}
调用上面的类
5
1
sunClass(18,"鲁梦瑶").also{
2
println(it.writeline())
3
}.also{
4
println(it.writeLine())
5
}
类属性,给类属性赋值,使用field
16
1
// 面向对象,给属性赋值
2
class AttributeClass{
3
// 自定义属性访问器
4
var name:String = ""
5
set(value){
6
field = value
7
}
8
get() = field
9
10
// 属性访问
11
var age:Int = 0
12
set(value) {
13
field = value
14
}
15
get() = field
16
}
可见性修饰符
11
1
public class{}
2
3
// 仅内部可用
4
private class{}
5
6
// 子类可用
7
protected class{}
8
9
// 相同module可用
10
internal class{}
11
延迟初始化,lateinit
16
1
// 延迟初始化
2
class lateinitClass{
3
4
lateinit var name:String;
5
6
// 初始化name值,只有在初始化后才能使用name
7
fun ready(){
8
name = "延迟初始化变量,必须初始化后才能使用";
9
}
10
11
fun battle(){
12
// 使用isInitialized判断name是否被初始化
13
if(::name.isInitialized)
14
println(name)
15
}
16
}
惰性加载
13
1
// 延迟加载,惰性初始化
2
// 只有在调用该变量时才会初始化
3
//
4
5
class byLazy{
6
val lazyConfig by lazy{
7
loadConfig()
8
}
9
10
fun loadConfig():String{
11
return "惰性加载";
12
}
13
}
is 和 as
16
1
// 使用 is 判断 是否某个类型
2
3
var a = "";
4
5
a is String
6
7
// 使用as 强制转换
8
9
open class a{}
10
11
class b :a(){}
12
13
val b = b();
14
15
// 把子类转为父类,
16
b as a;
不安全的转换
5
1
// 无法转换
2
var a :String = b as String;
3
4
// null 不能转换为 string
5
var a:String? = b as String?
安全转换
1
1
var a:String? = b as? String
与C#的 as 不同
7
1
// kotlin 的as 无需再次赋值,比如
2
3
(b as a); // 之后调用b即可
4
5
// c#如下, 需要使用新的对象赋值
6
7
var x = (b as a);
Any是所有 类的超类
相当于C#的object
4
1
// Any
2
fun anyclass(name:Any){
3
println(name is String)
4
}
匿名对象,objcet
17
1
open class objectTest {
2
open fun load(){
3
println("我是原生对象")
4
}
5
}
6
7
fun mian(){
8
// 匿名对象继承 objectTest
9
var overrideObject = object:objectTest(){
10
override fun load(){
11
println("我是一个对象,继承 objectTest类")
12
}
13
}
14
15
overrideObject.load()
16
17
}
声明一个对象
6
1
var objectCreated = object{
2
val name = "jack";
3
val age = 18;
4
}
5
6
println(objectCreated.name)
companion半生对象,像是其他语言的static
17
1
class companionClass{
2
companion object{
3
var config = "null";
4
5
fun load(_config:String){
6
config = _config
7
}
8
9
fun default(){
10
println(config)
11
}
12
}
13
}
14
15
// 调用
16
companionClass.load("config已经加载")
17
companionClass.default();
data class 数据类
8
1
// 数据类必须有最少一个参数
2
// 数据类,仅提供数据,比如获取的json,xml等需要赋值的类
3
data class dataClass(var x:Int,var y:Int) {
4
5
override fun toString(): String {
6
return "dataClass(x=$x, y=$y)"
7
}
8
}
复制 data class
4
1
val data =dataClass(30,12)
2
var dataClassCopy = data.copy()
3
4
println(dataClassCopy)
operator - 运算符重载,类本身不支持 + += - -=
但是可以重载运算符
14
1
class operatorClass(var max:Int,var min :Int) {
2
3
// 重写 plus 方法
4
operator fun plus(other:operatorClass) = operatorClass(max + other.max,min + other.min)
5
6
override fun toString(): String {
7
return "operatorClass(max=$max, min=$min)"
8
}
9
10
11
}
12
13
// 调用
14
(operatorClass(1,6) + operatorClass(23,64)).also{ println(it.toString())}

enum 枚举
7
1
enum class enumClass{
2
东,
3
南,
4
西,
5
北
6
}
7
初始化枚举
9
1
enum class enumClass(val value :Int) {
2
东(1),
3
南(2),
4
西(3),
5
北(4)
6
}
7
8
// 调用
9
enumClass.南.also { println(it.value) }
枚举方法
12
1
enum class enumClass(val value :Int) {
2
东(1),
3
南(2),
4
西(3),
5
北(4);
6
7
fun plus() = value +1;
8
}
9
10
// 调用
11
12
enumClass.南.plus().also(::println)
sealed - 密封类,某种意义上来说是enum的拓展
20
1
sealed class sealedClass {
2
object error:sealedClass();
3
class success(val notify:String):sealedClass();
4
5
}
6
7
// 使用 sealed
8
class sealedUse(var value:sealedClass){
9
fun mian(){
10
// when语句判断value的类型,然后做出相应动作
11
val status = when(value){
12
// 如果 = erro
13
is sealedClass.error ->"失败"
14
// 如果 = success
15
is sealedClass.success -> (value as sealedClass.success).notify
16
}
17
18
println(status)
19
}
20
}
泛型
28
1
// 泛型
2
class fanClass<T> (var age:T){
3
4
init{
5
println(age)
6
}
7
8
// 再次声明一个泛型
9
// 泛型函数
10
fun <R> create(value :()->R) : R{
11
return value();
12
}
13
}
14
15
class createFan{
16
17
fun mian(){
18
val fan:fanClass<Int> = fanClass(18)
19
20
// 他的返回值是一个泛型lambda,而lambda如果是最后一个参数可以用括号代替()
21
val fanRtrun = fan.create{
22
fan.age * 361
23
}
24
25
}
26
27
}
28
多参数vararg, C#里面的param
20
1
// 多个参数
2
class paramListClass<T>(vararg var listName:T) {
3
4
// 用泛型给array赋值时必须加 out
5
6
val listParam :Array<out T> = listName;
7
8
//
9
10
fun mian(index:Int):T{
11
return listParam[index];
12
}
13
14
}
15
16
// 调用
17
paramListClass(435,345,346,236,46,6).run{
18
for( item in 0 .. 5)
19
mian(item).also(::println)
20
}
协变 out, 逆变in
5
1
公式:
2
3
协变:IFoo<父类> = IFoo<子类>;
4
5
逆变:IBar<子类> = IBar<父类>;
协变 逆变在array中使用
23
1
// 协变和逆变
2
class UseArray<T>{
3
// 插入使用 in , 访问使用 out
4
// 父继承子类使用out,子类继承父类使用in
5
val list:Array<in T> = Array(5){};
6
7
8
fun mian(set:T){
9
list[0] = set;
10
println(list[0])
11
}
12
13
}
14
15
// 调用;
16
UseArray<String>().also{
17
it.list[1] = "String2";
18
it.list[2] = "String3";
19
it.list[3] = "String4";
20
it.list[4] = "String5";
21
}.also{
22
it.mian("第一个String")
23
}
判断 泛型类型 reified , 使用reified必须使用 inline
50
1
class reifiedClass<T> {
2
3
// reified 必须是 内联函数(inline)
4
inline fun <reified T> createOrRandow(create:()->T):T{
5
val list = listOf(
6
dog("dock",1),
7
man("jack",0)
8
)
9
// @shuffled 洗牌
10
val random = list.shuffled()?.firstOrNull();
11
12
// 判断是否 指定类型,如果是则为true,否则使用自定义lambda
13
return if(random is T){
14
15
random;
16
17
}else{
18
create();
19
}
20
}
21
}
22
23
open class Hub{
24
25
}
26
27
class dog(var name:String, var age:Int):Hub(){
28
override fun toString(): String {
29
return "dog(name='$name', age=$age)"
30
}
31
}
32
33
class man(var name:String, var status:Int):Hub(){
34
override fun toString(): String {
35
return "man(name='$name', status=$status)"
36
}
37
}
38
39
// 调用上面的类
40
class useReified{
41
42
//
43
fun mian(){
44
reifiedClass<Hub>().createOrRandow {
45
man("Tom",3)
46
}.run{
47
toString().run(::println)
48
}
49
}
50
}
函数式接口 fun interface
36
1
class funInterface{
2
3
/*
4
* 函数式 接口
5
* */
6
fun interface isCode{
7
fun invoke():String;
8
}
9
10
fun mianLambda(){
11
12
// 使用lambda调用函数式接口
13
val createCode = isCode{
14
"函数式接口,使用lambda调用"
15
}
16
17
createCode.invoke().run(::println)
18
19
}
20
21
// object 调用
22
fun mianVal(){
23
24
val createCode = object:isCode{
25
26
override fun invoke():String{
27
return "函数式接口,object调用"
28
}
29
30
};
31
32
createCode.invoke().run(::println)
33
}
34
35
}
36
拓展函数
32
1
class expandFun {
2
3
// companion,伴生对象,等同于其他语言的static
4
companion object{
5
6
}
7
}
8
9
// 拓展函数
10
fun expandFun.mian(){
11
println("拓展函数")
12
}
13
14
// 给companion添加拓展函数
15
fun expandFun.Companion.load(){
16
println("给 companion添加拓展函数")
17
}
18
19
// 泛型拓展
20
// 拓展后所有类型都具有 ExpandFun
21
fun <T> T.ExpandFun(){
22
println("泛型拓展函数")
23
}
24
25
// 可空拓展函数
26
// 这里的 可空类型是会执行的
27
/*
28
* 这里不会执行
29
* val a :String = null;
30
* a?.IsNullToNotify();
31
* */
32
fun String?.IsNullToNotify() = this ?: "null";
inner 内部类
10
1
// 内部类
2
class innerClass {
3
var studio = "visual studio ";
4
inner class innerSun{
5
fun load(){
6
// inner(内部类),可用调用上级的属性、方法
7
println(studio)
8
}
9
}
10
}
委托类 使用 by关键字
24
1
// 定义一个接口
2
interface BaseInterface{
3
fun ToString():String;
4
fun ToInt():Int;
5
}
6
7
// 定义一个类,用于实现BaseInterface
8
class useBaseInterface:BaseInterface{
9
override fun ToString(): String {
10
return "ToString Method";
11
}
12
13
override fun ToInt() = 666;
14
}
15
16
// 委托, 把 BaseInterface 赋值给变量 B
17
class delegate(var B:BaseInterface):BaseInterface by B {
18
}
19
20
// 调用, 先声明一个已经实现BaseInterface的类
21
val baseTo = useBaseInterface();
22
// 使用该类作为参数,即可调用BaseTo实现的方法
23
delegate(baseTo).ToString().run(::println)
24
delegate(baseTo).ToInt().run(::println)
懒加载,lazy配合 委托使用
24
1
// 几种懒加载实现
2
// 委托实现懒加载
3
class delegateAndLazy {
4
val load by lazy{
5
"字符串类型"
6
}
7
8
val loadTwo :String by lazy{
9
"字符串类型"
10
}
11
12
val loadThree = lazy{
13
"字符串类型"
14
}
15
}
16
17
// 调用
18
delegateAndLazy().also{
19
it.load.run(::println);
20
it.loadTwo.run(::println)
21
it.loadThree.run{
22
println(value)
23
}
24
}
委托, 映射类,通过字符串键属性名称
13
1
// 映射类
2
class myMap(val map:Map<String,Any?>){
3
// 通过字符串键 属性名称
4
val name:String by map
5
val age:Int by map
6
7
}
8
9
// 调用
10
myMap(mapOf("name" to " 当前字符串赋值给name,name的值","age" to 1)).let{
11
println(it.age)
12
println(it.name)
13
}
本文来自博客园,作者:Entity110,转载请注明原文链接:https://www.cnblogs.com/rdr2/p/15232093.html

浙公网安备 33010602011771号