Kotlin筆記


關(guān)鍵字

var ? val

var name = "張三"?

name = "李四" ?//true

name = 1//false ? ?name初始化時(shí)為String類型

val name = "趙五"

name = "你好"http://false ?name 用val修飾不能被改變 應(yīng)該相當(dāng)于final

函數(shù)

fun test(args:Array<String>):Int{

? ? return 3

}

判斷字符串是否相等

fun equalStr(i:String , j:String){

? ? i==j//true

}

equalStr("張三","張三")//true kotlin的==只比較對(duì)象是否相等,不比較內(nèi)存地址值

kotlin提供了一個(gè)equals的重載方法,用于忽略大小寫的比較 equals(str,true)//true為忽略 false 為不忽略

val ss = fun (name : String) = println("ssdd")// 函數(shù)名為ss的函數(shù) 默認(rèn)函數(shù)體為一條打印語句

fun 代表為函數(shù) 、test為函數(shù)名、args為參數(shù)名 Array<String>為參數(shù)類型 類型為字符串?dāng)?shù)組 、Int為返回值 返回值為Int類型

字符串模板 ${}

ex:

fun dayin(str:String):String{

? ? return "你的${str}真好"

}//運(yùn)行該函數(shù)時(shí)傳入的內(nèi)容會(huì)直接顯示在返回值里


null關(guān)鍵字

函數(shù)參數(shù)中加?表示參數(shù)可以傳null ?不加?表示不能傳入null值

ex:?

fun test(str:String?):String{

? ? return "別"+str

}

如果不加? 則調(diào)用函數(shù)傳入test(null)會(huì)報(bào)錯(cuò) 加上可以傳入空 test(null) -->別null

str : String!! 兩個(gè)嘆號(hào)表示一定不為空

!!表示當(dāng)前對(duì)象不為空的情況下執(zhí)行


when表達(dá)式(ex:考試滿分10分,9分還不錯(cuò),6分剛及格,6分一下不及格)

fun checkGrade(score:Int){

? ? when(score){

? ? ? ? 10 ?->println("滿分")

? ? ? ? 9????->println("還不錯(cuò)")

? ? ? ? 6 ? ?->println("及格了")

? ? ? ? else ? ?->println("不及格")

????}

}

fun xx(num:Int):String{

? ? var result = when(num){

? ? ? ? 1->"一"

? ? ? ? 2->"二"

? ? ? ? else->"三"

????}

????return result

}

Loop(循環(huán))和Range(區(qū)間)

var num = 1 .. 100 ?// [1,100] ? 頭尾都包含 1~100

var num2 = 1 until 100 // [1,100) ? ?包含頭不包含尾 1~99

var result = 0

fun test(){

? ? for(x in num){

? ? ? ? result = result+x

????}//循環(huán) 關(guān)鍵字in

}

step

var num = 1..16

num.count()//總數(shù)

for(x in num step 2){

打印結(jié)果為 1 3 5 7 9 11 13 15

}

List 和Map

var lists = listOf("你是誰","你在哪","你好啊","我不好")//定義一個(gè)集合list

var map = TreeMap<String,String>()

map["一"] = "one"

map["二"] = "two"

map["三"] = "three"

println(map["一"]) //"one"


函數(shù)和函數(shù)式表達(dá)

1、fun add(x:Int, y:Int) : Int = x+y

2、fun add(x:Int,y:Int):Int{

? ? return x+y

}

3、var i = {x : Int ,y : Int -> x+y}//變量i就是一個(gè)函數(shù) ?用時(shí) println( i(2,3))

4、var j : (Int,Int)->Int = {x,y -> x+y}// println(j(2,3))

//如果函數(shù)內(nèi)部只有一句return的語句 2的寫法可以省略成1的寫法

默認(rèn)參數(shù)和具名參數(shù)以及變長參數(shù)

val Pi= 3.1415926

fun getRectArea(PI:Float = Pi,radius:Float):Float{

? ? ? ? return 2*PI*radius

}

fun main(args:Array<String>){

? ? var area = getRectArea(radius = 2.0f)//具名參數(shù) ?調(diào)用方法后 因?yàn)榉椒ㄒ呀?jīng)給出pi是默認(rèn)參數(shù)的默認(rèn)值 所以直接用具名參數(shù) radius = 2.0f即可調(diào)用函數(shù)

? ? println(area)//打印圓的周長

}

字符串轉(zhuǎn)數(shù)字

var a = "13"
var b = 13
a = b.toString()
b = a.toInt()

異常處理

try{
? ??
}catch{
? ??
}finally{
? ??
}

循環(huán)

while(true){

}

var ssList = listOf<T>(x1,x2,x3,x4,x5)//建立一個(gè)集合 里面add五個(gè)元素

for(name ?in? ssList){


}

forEach循環(huán)

fun aa(){

? ? (0..100).forEach{

? ? ? ? if(50<= it) return@forEach

??????????????println(it)

????}

}

遞歸

fun digui(num:Int):Int{
? ? ????if(num==1){

? ? ? ? return 1;

????}else{

? ? return num *digui(num-1)

????}

}//階乘

遞歸計(jì)算100的階乘 ?用Long類型也裝不下 ?用BigInteger

fun degui2(n:Int):Int{

? ? if(n==1){

? ? return 1

}else{

? ? ? ? return n+degui2(n-1)

????}

}//累加

尾遞歸

tailrec fun weidigui(n:Int ,result :Int):Int{

? ? if(n==0){

? ? ? ? return 1

????}else{

? ? ? ? return weidigui(n-1,result+n)

????}

}// tailrec關(guān)鍵詞實(shí)現(xiàn)尾遞歸 要求返回值要是函數(shù)本身 所以這里用了兩個(gè)參數(shù)來寫做累加的函數(shù)

面向?qū)ο?封裝

private fun add(){}

繼承

open class father{

? ? var name = "張三"

? ? open fun add(){

????}

}

class son : father(){

? ? override fun add(){

????}

}

kotlin中繼承用:來表示 ? 子類繼承父類 父類必須有關(guān)鍵詞open 重寫父類方法時(shí) 父類方法必須有關(guān)鍵詞open?
子類復(fù)寫的方法上要有關(guān)鍵詞override?

重寫接口或父類方法都要有override關(guān)鍵字


抽象類

abstract class Human(var name : String){

? ? abstract fun eat()

}

class Man(name : String) : Human(name){

? ? override fun eat(){

? ? ? ? ? ? println("")

????} ? ?

}

接口

interface IMan{

? ? ?fun xiaodidi()

}

class Man : IMan{

? ? override fun xiaodidi(){

????????println("")

????}

}

實(shí)現(xiàn)接口不用加括號(hào) ? 繼承抽象類要加個(gè)括號(hào)

class Man:Human(),IMan{

? ? override fun xiaodidi(){

????}

? ? override fun eat(){

????}

}



var house = listOf<Human>(ren,taijian)

for(p in house){

? ? if(p is Man)

}

委托和代理

kotlin接口代理關(guān)鍵字 ? by

interface IWashBowl{

? ? fun washing()

}

class 大頭兒子 :IWashBowl{

? ? override fun washing(){

? ? ? ? 洗碗?

????}

}


class 小頭爸爸 :IWashBowl by?大頭兒子(){

? ? override fun washing(){

? ? ? ? 通過by可以調(diào)兒子的洗碗方法

? ? ? ? 大頭兒子().washing()

????}

}

單例模式

關(guān)鍵字:object

object class 大頭兒子{

? ? object關(guān)鍵詞修飾后大頭兒子類為單例 內(nèi)存中有且只有一個(gè)實(shí)例

}

大頭兒子() ?//表示創(chuàng)建了一個(gè)大頭兒子對(duì)象

大頭兒子 ?//表示沒有創(chuàng)建大頭兒子對(duì)象

剛才上面這段代碼

class 小頭爸爸 :IWashBowl?by?大頭兒子(){

? ? override fun washing(){

????????????大頭兒子().washing()//此處又重新創(chuàng)建了一個(gè)大頭兒子對(duì)象 因?yàn)榇箢^兒子類是單例的 所以不用加括號(hào)

}

}


class 小頭爸爸 :IWashBowl?by?大頭兒子{

? ? override fun washing(){

????????????大頭兒子.washing()//此處又重新創(chuàng)建了一個(gè)大頭兒子對(duì)象 因?yàn)榇箢^兒子類是單例的 所以不用加括號(hào)

}

}

枚舉

enum class Week{

? ? 星期一,星期二,星期三,星期四,星期五,星期六,星期天

}

印章類Sealed class ?

子類類型有限的class

有三個(gè)類 小母驢 小公馬 小公驢

sealed class Son {//她們?nèi)齻€(gè)類生出來的兒子只可能是騾子或驢 所以用sealed指定

? ? fun sayHello(){

? ? ? ? println("")

????}

? ? class 小小驢() :Son()

? ? class 小騾子() :Son()

}

關(guān)鍵字

lateinit ?延遲加載?只能修飾var 不能修飾val, 非kotlin基本類型

companion object 修飾靜態(tài)類和靜態(tài)方法

const只能修飾val,不能修飾var ?經(jīng)過const修飾的常量,才是java中理解的常量

const val NUM = 8

internal ?java里面有public protected private 和默認(rèn)修飾符, kotlin里多了個(gè)internal ?被internal修飾的 ?模塊內(nèi)可見(同一個(gè)module下)

as 強(qiáng)制轉(zhuǎn)換 ? , Kotlin里面,Int類型不能使用as轉(zhuǎn)換為String類型。第二,使用as運(yùn)算符進(jìn)行類型轉(zhuǎn)換,如果轉(zhuǎn)換錯(cuò)誤,會(huì)拋出異常

“?”運(yùn)算符,是kotlin提供的安全的類型運(yùn)算符,使用“?.”進(jìn)行類型轉(zhuǎn)換的時(shí)候,如果轉(zhuǎn)換失敗,則會(huì)返回null,而不會(huì)拋出異常

val a = 5 ??
val b = a as? String?

多行輸入符 三個(gè)雙引號(hào)

val str = """

? ? ? ? one

? ? ? ? two

? ? ? ? ? ? """

Unit ?如果函數(shù)不會(huì)返回任何有用值,那么他的返回類型就是?Unit


this關(guān)鍵字 ? ? ?用this@xx來表示 ?xx可以是類名也可以是函數(shù)名

operator fun ss() //告訴編譯器要定義一個(gè)運(yùn)算符的方法了

infix fun xs()// infix 為中綴表達(dá)式

可變參數(shù) ? 變長參數(shù) ?vararg?

fun asList<T> (vararg num :T) :List<T>{

}

變長參數(shù)相當(dāng)于java的可變參數(shù) (...)

調(diào)用時(shí) asList(1,2)?asList(1,2,3)?asList(1,2,3,4)

val a = array(1,2,3)

val list = asList(1,2,*a,4)?傳遞一個(gè) array 的內(nèi)容給函數(shù),我們就可以使用 * 前綴操作符 ?這個(gè)*只支持對(duì)于變長參數(shù)的場景 而且只能展開數(shù)組

inner ?內(nèi)部類

class xxx{

? ? private inner class xxx{

????}

}

字符串與對(duì)象地址比較

"11"=="11"http://true ?相當(dāng)于equals

new String("123")==="123"http://false 相當(dāng)于== ?比較的是內(nèi)存地址

內(nèi)聯(lián)擴(kuò)展函數(shù)之let

let擴(kuò)展函數(shù)的實(shí)際上是一個(gè)作用域函數(shù),當(dāng)你需要去定義一個(gè)變量在一個(gè)特定的作用域范圍內(nèi),
let函數(shù)的是一個(gè)不錯(cuò)的選擇;let函數(shù)另一個(gè)作用就是可以避免寫一些判斷null的操作。

類的構(gòu)造方法

class 妹子 constructor (var 長相:String,var 性格:String){

? ? init{ //init{}是構(gòu)造方法的方法體,在每一次創(chuàng)建一個(gè)對(duì)象的時(shí)候都會(huì)調(diào)用


????}

} ?//只有一個(gè)構(gòu)造方法時(shí)constructor可以省略

var 妹兒 :妹子 = 妹子(美,好)//根據(jù)構(gòu)造方法傳入?yún)?shù)長相美,性格好 new一個(gè)妹子 出來?

kotlin里的object ?是Any

空類型和智能類型的轉(zhuǎn)換

String?

String!!

import com.palmap.activity.sss

import com.palmap.activity.sss as bbb

同一個(gè)類下有相同類名的包導(dǎo)入 可以在導(dǎo)包的時(shí)候用as 給他起個(gè)別名

數(shù)組

val arrayOfInt : IntArray = intArrayOf(1,2,3)

val arrayOfChar : charArray = charArrayOf('a','b','c')

val arrayOfString : Array<String> = arrayOf("sss","www","vvv")

常量val和變量var

運(yùn)行時(shí)常量 ?val name = “你好啊”

編譯期常量 const val name = "嗯好"

類型推導(dǎo)

只要編譯器可以猜到你定義 的變量或常量的類型 就可以不用寫類型?

ex ? val ss = "sss"

val ss = 5

var x = getString()+5//String類型

Lambda表達(dá)式

Lambda表達(dá)式實(shí)際是一個(gè)匿名函數(shù)

寫法:

{[參數(shù)列表] - > [函數(shù)體,最后一行是返回值]}

val sum = {arg1 :Int,arg2 :Int -> arg1+arg2}

Lambda表達(dá)式類型舉例

()->Unit ? //無參,返回值為Unit

(Int) ->Int//傳入一個(gè)整型,返回一個(gè)整型

(String ,(String)->String) -> Boolean //傳入字符串,Lambda表達(dá)式,返回布爾

調(diào)用:

用()調(diào)用 ? ?== 用invoke調(diào)用

println(sum(1,2))

println(sum.invoke(1,2)) //invoke是kotlin里自帶的方法

Lambda表達(dá)式的簡化

args.forEach(::println)簡化過程

args.forEach({println(it)})

對(duì)于函數(shù)來說,如果他的最后一個(gè)參數(shù)是Lambda表達(dá)式,就可以把大括號(hào)里的內(nèi)容移到外面去

args.forEach(){println(it)}

如果小括號(hào)里什么也沒有,小括號(hào)可以省略

args.forEach{println(it)}

如果傳入的函數(shù)和需要接收的Lambda表達(dá)式是完全一樣的,還可以進(jìn)一步簡化

args.forEach(::println)


如果Lambda表達(dá)式只有一個(gè)參數(shù),默認(rèn)為it ?


fun main(args : Array){

? ? args.forEach{

? ? ? ? if(it=="q")return

? ? ? ? println(it)

????}

println("完事了")

} ?//執(zhí)行以后 打印語句“完事了”執(zhí)行不到 因?yàn)閒orEach屬于Lambda表達(dá)式 這里的return是直接return main函數(shù)如果想要return循環(huán) 可以給循環(huán)起個(gè)名字

fun main(args : Array){

? ? args.forEach ForEach@{

if(it=="q")return@ForEach

println(it)

}

println("完事了")

}?

表達(dá)式

條件表達(dá)式 ?中綴表達(dá)式?

val mode = if(){ xxx }else{ sss } 如果要這樣寫需要寫完整 就是有if也要有else?

多層循環(huán)嵌套 可以起名告訴編譯器要跳出哪個(gè)循環(huán)

Outter@for(,,,){

? ? Inner@while(,,,){

? ? if(..)break@Outter

}

}

解決兩個(gè)接口里有相同名字相同返回值相同參數(shù)的方法,方法名沖突的問題 用super<>泛型里面加上要調(diào)用那個(gè)方法的接口名字

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文是在學(xué)習(xí)和使用kotlin時(shí)的一些總結(jié)與體會(huì),一些代碼示例來自于網(wǎng)絡(luò)或Kotlin官方文檔,持續(xù)更新... 對(duì)...
    竹塵居士閱讀 3,321評(píng)論 0 8
  • Scala與Java的關(guān)系 Scala與Java的關(guān)系是非常緊密的!! 因?yàn)镾cala是基于Java虛擬機(jī),也就是...
    燈火gg閱讀 3,479評(píng)論 1 24
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,740評(píng)論 18 399
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,877評(píng)論 0 38
  • 晚上忙完躺在床上,一看時(shí)間——23:23。 本來當(dāng)天身體就不舒服,特意將做飯改成了煮面,想著不要太辛苦,可這會(huì)其實(shí)...
    葡萄紫耶閱讀 464評(píng)論 0 0