Kotlin基础
2021/9/6 6:07:34
本文主要是介绍Kotlin基础,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
intellid IDE查看函数注释 3 1
按一下 shift + q 显示提示框2 3
连按两下 shift +q 显示新的窗口使用Itellij IDE显示kotlin字节码,连续按两次shift 包名
x1
package cn.rxdidi2 3
// 导入包4
import cd.rxdidi常量
x1
const val a = "123":2 3
fun mian()4
{5
println("编译时常量只能在函数外申明")6
}变量
x1
var a;// 可以重复赋值2
val b; // 只能赋值一次,相当于常量3 4
var a :int = 1; // int类型的变量5 6
// 多行文本,.trimIndent()除去空格字符7
var str = """8
adf9
asdf10
asdf11
asdf12
asdf13
""".trimIndent()14
println(str)15 16
// val str = "字符串模板";17
println("类似C#的语法,$str")数组
x1
fun Aarr(){2
// 创建一个一维数组3
var arr = Array(5){i->i*5}4
// 循环输出数组,it = item5
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
x1
fun ForWhenWhileIf(){2
// 等同于 0 <= i && i <= 33
for (item in 0..3) println(item)4
// for循环数组, 相当于C#的foreach5
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#的foreach24
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否则false82 83
fun hasprefix(x:Any) = when(x){84
is String -> x.startsWith("prefix") // 如果字符串包含prefix开头则返回true85
is Int -> true // 如果是int类型返回true86
else -> false87
}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
// downTo14 15
for(item in 10 down 1) println(" 反向递送 = 10 9 8 7 .. 1 ");16 17
// step18
for (item in 10 step 2) println("每循环一次跳过两次");19 20
// until21 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 默认值 = 182
// FunctionParpam返回值为空,Unit = C#语言的void3
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键上面
x1
fun `我是反引号方法`(){2
println("反引号申明特殊字符方法")3
println("反引号申明特殊字符方法")4
}匿名函数
x1
fun `匿名函数`(){2
// 匿名函数使用方法就是C#的lambad3 4
var Anonymous = "用匿名函数判断此字符串重复的字符串数量".count({string -> string == '字'})5 6
println(Anonymous)7 8
}
匿名函数隐式返回
15 1fun `匿名函数隐式返回`(){2 3
// 匿名函数声明方法一4
val BlessingFunction1:()-> String = {5
"隐式返回默认返回最后一行,无需return"6
}7 8
// 匿名函数隐式返回29
val BlessingFunction2:() -> String10 11
BlessingFunction2 = {12
"隐式返回默认返回最后一行,无需return"13
}14
}15
匿名函数只有一个参数时,可以用it代替
8 1fun `匿名函数只有一个参数时`(){2
var AnonymousIt:(Str:String)->String = {3
it->4
"匿名函数只有一个参数时,可以用it代替:{$it}"5
}6 7
println(AnonymousIt("我是匿名函数的参数,当匿名函数只有一个参数时可以用it代替"))8
}
匿名函数类型推断,大大减少代码量
x1
var BlessingFunction = {2
"当匿名函数没有参数时,简略写法可以这么写"3
}4 5
var blessingFunction2 = {6
Str:String,int:Int->7
"当匿名函数有参数时,简略写法:参数一 = $Str, 参数二 = $int"8
}
匿名函数就是Lambda#
11 1kotlin的Lambda2 3
()-> String {4
Param:String ->5
"我是kotlin的lambda函数,参数一调用:$Param"6
}7 8
C#的Lambda9 10
Func<参数 Param, string 返回值>= a => $"Lambda参数一的值为: {a}";11
当函数参数是lambda时
30 1fun `当Lambda被当作参数时`(){2 3
var Lambda:(String) -> String = {4
it ->5
it // 返回it , it = 默认参数6
}7 8
// 调用函数,函数内含有Lambda9
// 使用此方法调用,感觉非常麻烦10 11
println("使用常规方法调用函数")12
val a = FunLambda(18,Lambda)13 14
// 调用函数,函数内含有Lambda15
// 括号里面写函数的参数,大括号里面就是Lambda16 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 1fun `函数除了可以调用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 1var str:String? = "可空类型";
安全调用操作符
5 1var str:String? = "可空类型";2
str = null;3 4
//可空类型必须使用?,否则会报错5
str?.trim();
可空类型使用let函数
19 1// 可空字符串使用 let函数2
fun nullLet(){3 4
var str:String? = "本字符串可以为空"5
str = null6 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 = null7
// 不为空为左,为空为右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 +110
str!!.plus("+1");11 12
}catch (e:Exception){13
println(e)14
}15 16 17
}18 19
// 自定义异常,继承Exception20
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) = strList12 13
println(str1)14
}
replace(字符串替换) + regex(正则表达式)
1// replace2
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.value12
}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
// = true8
println(str1 == str2)9 10
// = false11
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 ,但四舍五入之后为107
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 * it8
}9
println(str)10 11
// let + :? 代替if else12
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 else30
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
// 可以使用多个run15 16
var resultLength = result.run(::textISlength)17
?.run(::textLengthGreaterThan)18 19
println(resultLength)20 21
}22 23
fun textISlength(text:String?) = text?.length24
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
length5
}6 7
var b = with("判断字符串长度"){8
length9
}10 11
println(a)12
println(b)13 14 15
}
also
1// also 跟 let 函数相似, also 接收对象,返回接受的对象, let 接收对象,返回lambda2
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// takeif2
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 当判定条件为假时返回对像,为真时返回null2
fun takeunless(){3
// 如果 isHidden为假则执行后面的函数,如果为真则返回null4
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// list2
fun list(){3
var strlist :List<String> = listOf("a","b","c")4 5
// 访问指定索引,如果不存在则为自定义值,Unknown6
println(strlist.getOrElse(3){"Unknown"})7 8
// 访问指定索引值,如果为空,则 = Unknown9
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// mutator2
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 list2
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 1fun `解构语法忽略赋值`(){2
val list = listOf("a","b","c")3 4
// 使用下划线忽略对b的赋值5
val (a,_,b) = list6 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// 可变的Setlist2
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
// 去重复元素函数 distinct9
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 1class 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
// 构造函数,无需constructor7 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关键字,其变量或方法可以被继承同样使用open23
open class parentClass(_name:String, _age:Int){24
// 子类不能重写父类的 var ,比如把var 覆盖为 val25
open var name = "";26
open var age = 0;27 28
init {29
name = _name;30
age = _age31
}32 33
open fun writeLine() :String{34
return "年龄 = ${age} , 姓名= ${name}"35
}36
}37 38
// 子类, 使用override39 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
// 如果要调用父类的属性或方法可以使用super49
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 1sunClass(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 = value7
}8
get() = field9 10
// 属性访问11
var age:Int = 012
set(value) {13
field = value14
}15
get() = field16
}
可见性修饰符
11 1public 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值,只有在初始化后才能使用name7
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 String6 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 不能转换为 string5
var a:String? = b as String?
安全转换
1 1var 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
// Any2
fun anyclass(name:Any){3
println(name is String)4
}
匿名对象,objcet
17 1open class objectTest {2
open fun load(){3
println("我是原生对象")4
}5
}6 7
fun mian(){8
// 匿名对象继承 objectTest9
var overrideObject = object:objectTest(){10
override fun load(){11
println("我是一个对象,继承 objectTest类")12
}13
}14 15
overrideObject.load()16 17
}
声明一个对象
6 1var objectCreated = object{2
val name = "jack";3
val age = 18;4
}5 6
println(objectCreated.name)
companion半生对象,像是其他语言的static
17 1class companionClass{2
companion object{3
var config = "null";4 5
fun load(_config:String){6
config = _config7
}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 1val data =dataClass(30,12)2
var dataClassCopy = data.copy()3 4
println(dataClassCopy)
operator - 运算符重载,类本身不支持 + += - -=
但是可以重载运算符
14 1class 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 1enum class enumClass{2
东,3
南,4
西,5
北6
}7
初始化枚举
9 1enum class enumClass(val value :Int) {2
东(1),3
南(2),4
西(3),5
北(4)6
}7 8
// 调用9
enumClass.南.also { println(it.value) }
枚举方法
12 1enum 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 1sealed class sealedClass {2
object error:sealedClass();3
class success(val notify:String):sealedClass();4 5
}6 7
// 使用 sealed8
class sealedUse(var value:sealedClass){9
fun mian(){10
// when语句判断value的类型,然后做出相应动作11
val status = when(value){12
// 如果 = erro13
is sealedClass.error ->"失败"14
// 如果 = success15
is sealedClass.success -> (value as sealedClass.success).notify16
}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 * 36123
}24 25
}26 27
}28
多参数vararg, C#里面的param
20 1// 多个参数2
class paramListClass<T>(vararg var listName:T) {3 4
// 用泛型给array赋值时必须加 out5 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 , 访问使用 out4
// 父继承子类使用out,子类继承父类使用in5
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 1class 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,否则使用自定义lambda13
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 1class 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 1class expandFun {2 3
// companion,伴生对象,等同于其他语言的static4
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
// 拓展后所有类型都具有 ExpandFun21
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
// 定义一个类,用于实现BaseInterface8
class useBaseInterface:BaseInterface{9
override fun ToString(): String {10
return "ToString Method";11
}12 13
override fun ToInt() = 666;14
}15 16
// 委托, 把 BaseInterface 赋值给变量 B17
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 map5
val age:Int by map6 7
}8 9
// 调用10
myMap(mapOf("name" to " 当前字符串赋值给name,name的值","age" to 1)).let{11
println(it.age)12
println(it.name)13
}
这篇关于Kotlin基础的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-01-06Kotlin委托属性(1)
- 2023-06-15Kotlin协程-那些理不清乱不明的关系
- 2023-06-08[Kotlin Tutorials 21] 协程的取消
- 2023-05-26Kotlin难点
- 2023-02-23【备战春招】第16天 Kotlin实用技巧
- 2023-02-23【备战春招】第15天 Kotlin扩展Extensions技术探秘
- 2023-02-22【备战春招】第14天 深入理解Kotlin注解
- 2023-02-21【备战春招】第12天 深入理解Kotlin类与接口
- 2023-02-21【备战春招】第13天 深入理解Kotlin泛型
- 2023-02-18【备战春招】第10天 Kotlin方法与Lambda表达式