Kotlin學習-基礎篇(一)

Kotlin簡介

  • 來自于著名的IDE IntelliJ IDEA(Android Studio基于此開發(fā)) 軟件開發(fā)公司 JetBrains(位于東歐捷克)
  • 起源來自JetBrains的圣彼得堡團隊杨刨,名稱取自俄羅斯圣彼得堡附近的一個小島(Kotlin Island)
  • 一種基于JVM的靜態(tài)類型編程語言但骨,2017年谷歌I/O大會確定Kotlin為Android的官方語言

Kotlin應用不同領(lǐng)域

  • Kotlin-Script腳本編寫
  • Kotlin-Android項目開發(fā)
  • Kotlin-JavaScript前端項目開發(fā)
  • Kotlin-SpringBoot服務端項目開發(fā)
  • Kotlin-Native項目開發(fā)

Kotlin開發(fā)環(huán)境

  • 需要在IDE中安裝Kotlin插件;Android Studio3.0以上

Kotlin的優(yōu)點

  • 簡潔(不用判斷NullPointException,不需要寫分號等)
  • 100% 兼容 Java
  • 類型自動轉(zhuǎn)換并使用

定義變量

val a: Int = 1  // 顯式標明類型钱反,立即賦值  
val b = 2   // 自動推斷出 `Int` 類型  
var c: Int  // 如果沒有初始值類型不能省略  
c = 3       // 明確賦值

var和val的區(qū)別

  • var是一個可變變量,這種聲明變量的方式和java中聲明變量的方式一樣征讲。
  • val是一個只讀變量,這種聲明變量的方式相當于java中的final變量,以后不能被改變脓钾。
var name = "我是可改變的"  
println(name)  
name = "我真的是可改變"  
println(name)  
val finalValue = "我是不可改變的";  
println(finalValue); 

類定義

  • 在Kotlin中所有類都有一個共同的超類Any
//類定義洗鸵,繼承類和實現(xiàn)接口
class FeedBackActivity : NativeBaseActivity(), View.OnLongClickListener, BitmapUtil.SaveImageCall {
    
}
  • 創(chuàng)建類的實例
val invoice = Invoice()
val customer = Customer("Joe Smith")
//注意 Kotlin 并沒有 new 關(guān)鍵字越锈。

函數(shù)定義

Kotlin 中的函數(shù)使用 fun 關(guān)鍵字聲明,參數(shù)即 name: type膘滨。參數(shù)用逗號隔開

fun double(x: Int): Int {
    return 2 * x
}
  • Int 返回類型可以省略
fun sum(a: Int, b: Int): Int {
    return a + b
}

也可以

fun sum(a: Int, b: Int) = a + b
  • 減少方法重載
//支持默認參數(shù)值甘凭,減少方法重載
fun showToast(message: String, duration:Int = Toast.LENGTH_LONG) {
    Toast.makeText(this, message, duration).show()
}

//調(diào)用方式:沒有默認值的參數(shù),調(diào)用時火邓,必須填寫
showToast("toast");
showToast("toast", Toast.LENGTH_LONG);
  • main方法比較
//Java
public static void main(String[] args){

}
//Kotlin
fun main(args:Array<String>){
   
}

主次構(gòu)造函數(shù)

在Kotlin中的一個類可以有一個主構(gòu)造函數(shù)和一個或多個次構(gòu)造函數(shù)

  • 主構(gòu)造函數(shù):帶有類名的為主構(gòu)造函數(shù)(只有一個)
  1. 主構(gòu)造函數(shù)不能包含任何的代碼丹弱。初始化的代碼可以放到以 init 關(guān)鍵字作為前綴的初始化塊
  2. 主構(gòu)造函數(shù)中聲明的屬性可以是可變的(var)或只讀的(val)
//如果構(gòu)造函數(shù)有注解或可見性修飾符,這個 constructor 關(guān)鍵字是必需的铲咨,并且這些修飾符在constructor前面:
class Customer public @Inject constructor(name: String) { …… }

//無修飾可不寫constructor關(guān)鍵字
class Customer (name: String) {
    var a :Int = 1
    init{……}
}
  • 次構(gòu)造函數(shù):不帶類名并且有constructor關(guān)鍵字修飾的函數(shù)為次構(gòu)造函數(shù)(可以一個或多個)躲胳,并且只能存在主構(gòu)造函數(shù)代碼塊之內(nèi)
//如果類有一個主構(gòu)造函數(shù),每個次構(gòu)造函數(shù)需要委托給主構(gòu)造函數(shù)纤勒, 可以直接委托或者通過別的次構(gòu)造函數(shù)間接委托坯苹。委托到同一個類的另一個構(gòu)造函數(shù)用 this 關(guān)鍵字即可:
class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}
  • 無參構(gòu)造函數(shù)
  1. 如果沒有構(gòu)造函數(shù),將會默認一個無參數(shù)構(gòu)造函數(shù)
  2. 如果主構(gòu)造函數(shù)的所有的參數(shù)都有默認值摇天,編譯器會生成一個額外的無參構(gòu)造函數(shù)粹湃,它將使用默認值恐仑。
//如構(gòu)造函數(shù)為私有,需用private修飾
class DontCreateMe public constructor () {

}

class Customer(val customerName: String = ""){}

函數(shù)調(diào)用

val result = double(2)
Sample().foo() // 創(chuàng)建類 Sample 實例并調(diào)用 foo

字符串模板

  • 字符串可以包含模板表達式,以$開始
val book = Book("Thinking In Java", 59.0f, "Unknown")
val extraValue = "extra"
Log.d("MainActivity", "book.name = ${book.name}; book.price=${book.price};extraValue=$extraValue")

區(qū)間

區(qū)間表達式由具有操作符形式 .. 的 rangeTo 函數(shù)輔以 in 和 !in 形成为鳄。

if (i in 1..10) { // 等同于 1 <= i && i <= 10
    println(i)
}

//順序
for (i in 1..4) print(i) // 輸出“1234”
for (i in 4..1) print(i) // 什么都不輸出

//倒序
for (i in 4 downTo 1) print(i) // 輸出“4321”

//要創(chuàng)建一個不包括其結(jié)束元素的區(qū)間裳仆,可以使用 until 函數(shù):
for (i in 1 until 10) {   // i in [1, 10) 排除了 10
     println(i)
}

//能否以不等于 1 的任意步長迭代數(shù)字? 當然沒問題孤钦, step() 函數(shù)有助于此:每循環(huán)到第二個元素就剔除

for (i in 1..4 step 2) print(i) // 輸出“13”

for (i in 4 downTo 1 step 2) print(i) // 輸出“42”


控制流:if歧斟、when、for司训、while

if表達式

if和Java用法一致

val max = if (a > b) a else b
when表達式

when它能完全取代switch/case构捡,也可以用來取代 if-else if鏈,并且還有很多新的特性壳猜。

如果其他分支都不滿足條件將會求值else分支勾徽。 如果 when 作為一個表達式使用,則必須有 else 分支统扳, 除非編譯器能夠檢測出所有的可能情況都已經(jīng)覆蓋了喘帚。

//分支條件可以是:Int,區(qū)間,方法,字符串,對象等
when (x) {
    0, 1 -> print("x == 0 or x == 1")
    in 2 -> print("x == 2")
    in 3..8 -> print("x == 3..8")
    parseInt(s)-> print("parseInt")
    is String -> print("x is String")
    else -> print("otherwise")
}


fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")//智能轉(zhuǎn)換
    else -> false
}

//when 也可以用來取代 if-else if鏈咒钟。 如果不提供參數(shù)吹由,所有的分支條件都是簡單的布爾表達式,而當一個分支的條件為真時則執(zhí)行該分支:
when {
    x.isOdd() -> print("x is odd")
    x.isEven() -> print("x is even")
    else -> print("x is funny")
}

for 循環(huán)
for (item in collection) print(item)

//循環(huán)體可以是一個代碼塊朱嘴。
for (item: Int in ints) {
    // ……
}


for (i in 1..3) {
    println(i)//輸出“123”
}

for (i in 6 downTo 0 step 2) {
    println(i)//輸出“6420”
}

//如果想索引遍歷倾鲫,可以通過indices函數(shù)
for (i in array.indices) {
    println(array[i])
}

//或者你可以用庫函數(shù) withIndex:
for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}
//輸出:
the element at 0 is a
the element at 1 is b
the element at 2 is c

While 循環(huán)

while 和 do..while 照常使用,省略

Kotlin 有三種結(jié)構(gòu)化跳轉(zhuǎn)表達式:

  • return萍嬉,默認從最直接包圍它的函數(shù)或者匿名函數(shù)返回乌昔。
  • break,終止最直接包圍它的循環(huán)壤追。
  • continue磕道,繼續(xù)下一次最直接包圍它的循環(huán)。

特殊符號?和!!

  • ?:表示當前是否對象可以為空

  • !!: 表示當前對象不為空的情況下執(zhí)行

private var cloth_Rv: RecyclerView ?= null
cloth_Rv!!.setHasFixedSize(true)

可見性修飾符

類行冰、對象溺蕉、接口、構(gòu)造函數(shù)悼做、方法疯特、屬性和它們的 setter 都可以有 可見性修飾符。 在 Kotlin 中有這四個可見性修飾符:private贿堰、 protected辙芍、 internal 和 public。 如果沒有顯式指定修飾符的話,默認可見性是 public

  • internal —— 能見到類聲明的 本模塊內(nèi) 的任何客戶端都可見其 internal 成員
  • 其它和Java一樣

重要關(guān)鍵字

Any

在Kotlin中所有類都有一個共同的超類Any,Any并不是Object

open

  1. 修飾類:表示能被繼承
  2. 修飾方法:表示需要重寫

final故硅、open庶灿、abstract、override對比

修飾符 相應類的成員 注解
final 不能被重寫 在kotlin中默認所有的方法和類都是final屬性
open 可以被重寫 需要被明確指出
abstract 必須要重寫 不能被實例化吃衅,默認具有open屬性
override 覆寫超類的方法 如果沒有被指定為final往踢,則默認具有open屬性

companion 伴生對象

//可以省略Factory
class MyClass {
     companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()

內(nèi)部類和匿名內(nèi)部類

  • 內(nèi)部類
//如果需要調(diào)用成員變量,需要用inner修飾內(nèi)部類
class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}

val demo = Outer().Inner().foo() // == 1
  • 匿名內(nèi)部類
//匿名內(nèi)部類
textView.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
       //...
    }
})

擴展

函數(shù)擴展可以讓你對任意類進行擴展徘层,而不用繼承等等復雜的操作峻呕。

對參數(shù)的解釋:

  • Context:表示函數(shù)的接收者,也就是函數(shù)擴展的對象
  • . :擴展函數(shù)修飾符
  • toast:擴展函數(shù)的名稱或者屬性名稱

擴展函數(shù)

fun Context.showToast(content: String, duration: Int = Toast.LENGTH_SHORT): Toast {
    val toast = Toast.makeText(MyApplication.context, content, duration)
    toast.show()
    return toast
}

這樣只要是Context的子類趣效,任何地方都可以調(diào)用Toast了

擴展屬性

var View.padLeft: Int
    set(value) {
        setPadding(value, paddingTop, paddingRight, paddingBottom)
    }
    get() {
        return paddingLeft
    }
    //調(diào)用 textView.padLeft = 16

Any擴展函數(shù)

apply

  • apply 是 Any 的擴展函數(shù)瘦癌,因而所有類型都能調(diào)用。
  • apply 接受一個lambda表達式作為參數(shù)跷敬,并在apply調(diào)用時立即執(zhí)行讯私,apply返回原來的對象。
  • apply 主要作用是將多個初始化代碼鏈式操作西傀,提高代碼可讀性斤寇。
val task = Runnable { println("Running") }
val thread = Thread(task)
thread.setDaemon(true)
thread.start()

以上代碼可以簡化為:

val task = Runnable { println("Running") }
Thread(task).apply { setDaemon(true) }.start()

如有問題歡迎留言,感謝支持和關(guān)注。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拥褂,一起剝皮案震驚了整個濱河市娘锁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺鹃,老刑警劉巖莫秆,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悔详,居然都是意外死亡馏锡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門伟端,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匪煌,你說我怎么就攤上這事责蝠。” “怎么了萎庭?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵霜医,是天一觀的道長。 經(jīng)常有香客問我驳规,道長肴敛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮医男,結(jié)果婚禮上砸狞,老公的妹妹穿的比我還像新娘。我一直安慰自己镀梭,他們只是感情好刀森,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著报账,像睡著了一般研底。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上透罢,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天榜晦,我揣著相機與錄音,去河邊找鬼羽圃。 笑死乾胶,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的统屈。 我是一名探鬼主播胚吁,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愁憔!你這毒婦竟也來了腕扶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤吨掌,失蹤者是張志新(化名)和其女友劉穎半抱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膜宋,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡窿侈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了秋茫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片史简。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肛著,靈堂內(nèi)的尸體忽然破棺而出圆兵,到底是詐尸還是另有隱情,我是刑警寧澤枢贿,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布殉农,位于F島的核電站,受9級特大地震影響局荚,放射性物質(zhì)發(fā)生泄漏超凳。R本人自食惡果不足惜愈污,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轮傍。 院中可真熱鬧暂雹,春花似錦、人聲如沸金麸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挥下。三九已至揍魂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棚瘟,已是汗流浹背现斋。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偎蘸,地道東北人庄蹋。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像迷雪,于是被迫代替她去往敵國和親限书。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344