kotlin基礎筆記
kotlin目前是android第一開發語言
優點:簡潔 空值安全 100%相容java 函數語言程式設計 協程 DSL
開發工具:idea as eclipse
kotlin檔案的字尾是: .kt
main函式是程式的入口
基本資料型別:Boolean Byte Char Short int Float Double Long
智慧型別判斷:自動選擇使用java的基本資料型別
kotlin型別型別安全
高精度:BifDecimal
var big:BigDecimal=BigDecimal(val"0.1212121212112")
var
val:不可變數(與java的final修飾的變數類似)
刪除空格 : .trim()
刪除空格前導 : .trimMargin(marginPrefix:"")
字串比較: 字串1 = = = 字串2(=== 比較字串引用地址)
元祖資料:
二元元祖 Pair 儲存2個數據
三元元祖 Triple 儲存3個數據
val pair:Pair<String,Int>=Pair("ada",20)
//pair.first 取第一個資料
空值處理:
String : 非空型別
String? : 可空型別
?. : 空安全呼叫符號 ,如果為空不執行後面的程式碼 !!. : 非空斷言(一定不為空,如果為空,還是會報錯)
控制檯輸入函式 readLine()
控制檯輸出println()
函式(程式執行的片段):fun修飾
1.無引數,無返回值
2.有引數,無返回值
3.無引數,有返回值
4.有引數,無返回值
字串模版: $ 站位符
for迴圈:
val s="asdasdasdasd" for(a:Char in s){ } s.forEach(){ printin(it) }//it是每個元素
//加上index角標的for迴圈
for ((index,c) in s.withIndex()) {
println("index=$index c=$c")}
s.forEachIndexed{ index, c-> }//角標 index 元素 c
break:跳出迴圈
continue:跳出本次迴圈
return:結束方法
loop:標籤處返回
[email protected](){ //loop可以使任意字元
for(){
if(){
[email protected]
}
}
}
do while
while
區間:
var r:IntRange=1…100 //1到100
var r=IntRange(1,100)
var r:IntRange=1 until 100 //1到99
IntRange LongRange CharRange(字元區間(a..z))
反向區間 1.val r:IntProgression=10 downTo 1
2.val r2:IntProgression=r.reversed() //區間反轉
if:return if (a > b) a - b else b - a
list:
例如: var lists=listOf("121","12312")
for((i,e) in lists.withIndex()){
println("$i $e") //i是索引 e是元素
}
map:
例如 :var map=TreeMap<String,String>()
map["hao"] ="good"
println(map["hao"])
陣列:
例如:var a=arrayof(12,3,4);
var a= IntArray(10) //定義元素個數為10個的Int陣列
val intArr = IntArray(10){ 0} //定義了一個長度為10的Int資料型別並且所有元素都為0
陣列迴圈
for (s in array) { println(s)}
array.forEach { println(it)}
for迴圈遍歷元素以及角標
for ((index,s) in array.withIndex()) { println("角標$index s=$s")}
array.forEachIndexed { index, s -> println("角標=$index 元素=$s")}
修改某一個位置上的元素
newArr[0] = 20 //將角標0元素值設定為20
newArr.set(4,20)//將角標4元素值設定為20
查詢第一個元素2
第一種:
arr.indexOf(2)
第二種:
arr.indexOfFirst {it==2 }
查詢最後一個元素2
第一種:
arr.lastIndexOf(2)
第二種:arr.indexOfLast { it == 2 }
When:多分支選擇,加強版的switch
基本表示式:when (age) {
7 -> return "開始讀小學"
12 -> { println("開始讀中學") return "開始讀小學" }
else -> return "讀社會大學“}
加強版:when(ele){
10-> println("它10歲") is Int-> println("傳遞的是年齡")
in 1..10-> println("在10歲以內")
!in 1..10-> println("不在10歲以內")
else-> println("所有情況都不滿足")}
表示式不帶引數: when{
ele == 10-> return "它十歲"
ele is Int-> return "傳遞的是年齡"
ele in 1..10->return "在10歲以內"
ele !in 1..10-> return "不在10歲以內"
else-> return "所有情況都不滿足“}
表示式返回值:val s = when {
ele == 10 -> "它十歲"
ele is Int -> "傳遞的是年齡"
ele in 1..10 -> "在10歲以內"
ele !in 1..10 -> "不在10歲以內"
else -> "所有情況都不滿足“}
函式表示式:
fun add(a:Int,b:Int):Int{ return a+b}
函式體只有一行,可以簡寫
fun add(a:Int,b:Int):Int = a+b
還可以更加簡潔
fun add(a:Int,b:Int) = a+b
定義函式變數儲存函式引用
val addFun1:(Int,Int)->Int = ::add
執行這個函式
第一種: addFun1(10,20)
第二種: addFun1.invoke(10,20)
定義函式變數時定義函式(這個函式也是求a+b的和)
var addFun:(Int,Int)->Int={a,b->a+b }
執行這個函式
第一種:val result = addFun(10, 20)
第二種:val result = addFun.invoke(10, 20)
預設引數:定義函式變數時可以指定預設值
fun info(name:String = "zhangsan",age:Int){ println("name=$name age=$age")}
具名引數:呼叫函式時可以指定引數(沒有順序)
info(age=age,name = "李四")
可變引數:
如果接收的引數個數不確定,可以用可變引數表示
fun add(vararg arr: Int): Int {
var result = 0
arr.forEach {
result += it
}
return result}
頂層函式:Kotlin裡面函式可以獨立於class類存在,這就是頂層函式
巢狀函式:函式裡面定義函式
fun main(args: Array<String>) {
var name = "張三"
fun haha(age:Int){
println("名字$name 年紀$age")
return //只能返回當前函式 不會返回main函式
}
haha(20)
println("呵哈")
}
異常處理:
程式丟擲異常
fun add(a: Int, b: Int): Int {
if (b == 0) { throw Exception("我是異常")
} else { return a / b }}
Kotlin沒有受檢異常
處理異常
try { add(10, 0)
} catch (e: Exception) { println("不能為0")
}finally { println("一定執行的程式碼")}
遞迴:直接或間接呼叫自身的一種方法,只需少量的程式就可描述出解題過程所需要的多次重複計算
例如:
遞迴實現連續資料之和1..100
fun allAdd(n: Int): Int {
if (n == 1) { return 1
} else { return n + allAdd(n - 1) }}
遞迴實現菲波那切數列1.1.2.3.5.8
tailrec fun fib(n: Int): Int {
if (n == 0) return 0
if (n == 1) return 1
if (n > 1) return fib(n - 2) + fib(n - 1)
return 0}
尾遞迴:
函式在呼叫自己之後沒有執行其他任何的操作就是尾遞迴
實現尾遞迴優化
tailrec fun gsTaAdd(n: Int,result:Int): Int {
if (n == 1) {
return result+1
} else {
return gsTaAdd(n - 1,result+n) }}
運算子過載:
主構和次構函式:
主構:class Person(var name:String,var age:Int){}
次構函式:(次構函式必須要呼叫主構)
class Person(name:String,age:Int){ constructor(name: String,age: Int,phone:String):this(name, age)}
次構函式間的呼叫:class Person12(name:String,age:Int){
constructor(name: String,age: Int,phone:String):this(name, age)
constructor(name: String,age: Int,phone: String,email:String):this(name, age, phone)}
init:呼叫主構函式,呼叫次構函式,都會執行init
class Person(){//這裡如果沒有()就代表沒有無參建構函式 init { println("執行了init方法") } constructor(name:String):this()}
主構 次構 init呼叫順序:無論呼叫主構還是次構都會執行init
呼叫次構先執行init再執行次構中的操作
儲存主構中的引數:
在init方法中儲存:class Person(name:String,age:Int){ var name = "" var age = 0 init { this.name = name this.age = age } }
變數申明時儲存:class Person(name:String, age:Int){ var name = name var age = age}
主構函式引數的var和val:
引數沒有var和val修飾,引數在其他地方不能使用class Person8(name:String,age:Int){}
引數有var修飾,可以使用,可以修改class Person(var name:String,var age:Int){ override fun toString(): String { return “Person(name=
age)” }} val person = Person8(“張三”,20)person.name = “李四”
引數有val修飾,可以使用,不能修改class Person(val name:String, val age:Int){ override fun toString(): String { return “Person(name=
age)” }}
次構函式引數使用:次構中引數不能加var或者val修飾
次構引數使用 class Person11(var name: String, var age: Int) { var phone: String = “” constructor(name:String,age:Int,phone:String):this(name,age){ this.phone = phone }}
封裝:隱藏內部細節實現,只保留對外介面 通過private
class Restaurant{ //點餐 fun order(){ getTicket() } private fun getTicket(){ println(“取到點餐票了”) }}
類的繼承:
普通繼承open關鍵字open class Father{ var name:String = “” var age:Int = 0 open fun sayHello(){ println(“父類hello”) }}class Son:Father(){ }
方法繼承和屬性繼承:方法繼承和屬性繼承也都是通過open關鍵字
open class Father2{ open var name = “小頭爸爸” var age = 30 open fun sayHello(){ println(“hello”) }}class Son2: Father2(){ override var name = “大頭兒子” override fun sayHello() { super.sayHello() }}
繼承父類主構:
子類主構繼承父類主構:
open class Human(val name:String,var age:Int)class Man(name:String,age:Int):Human(name,age)
子類次構繼承父類主構:
open class Human(var name:String, var age:Int)class Woman: Human { constructor(name:String,age:Int):super(name,age) constructor(name:String,age:Int,phone:String):super(name,age) constructor(name:String,age:Int,phone:String,email:String):this(name,age,phone)}
抽象類:
抽象類是具體型別的抽象,用abstract表示
abstract class IHuman1(val name:String,val age:Int){ abstract fun eat()}
介面:
介面用interface 表示
interface Ride{ fun rideBike()}
抽象類反映事物的本質,介面代表能力
類只能單繼承,介面可以多實現
多型:多型就是同種功能不同的表現形式.
定義抽象類和子類
open abstract class Animal{ abstract fun call()}class Dog: Animal() { override fun call() { println(“汪汪汪”) } }class Cat:Animal(){ override fun call() { println(“喵喵喵”) } }呼叫 val animal1:Animal = Dog()val animal2:Animal = Cat()
智慧型別轉換:當判斷出型別之後就自動將型別轉換成該型別了
open class IAnimal class IDog : IAnimal() { fun wangwang() { println(“狗汪汪叫”) }}val animal1: IAnimal = IDog()if (animal1 is IDog) animal1.wangwang()
巢狀類和內部類:
巢狀類:class OutClass{ var outName = “張三” class InClass{ fun sayHello(){ //println(outName) 無法訪問外部類中欄位 } }}
內部類inner: class OutClass1{ var outName = “張三” inner class InClass{ fun sayHello(){ println(outName) //可以訪問外部類中欄位 } }}
內部類中使用this:
可以指定內部this和外部this:
class OutClass2 { var name = “張三” inner class InClass { var name = “李四” fun sayHello() { println([email protected]) } }}
泛型:
泛型就是引數化型別class Box(var value: T)//不知道具體傳遞的型別
中綴表示式:
class A {
infix fun p(str: String): Unit {
println(str)
}
}
A() p "haha"