重要的網(wǎng)址
插件官網(wǎng)地址 (studio 有時更新不下來自己下載手動安裝)
https://plugins.jetbrains.com/plugin/6954-kotlin
接口
使用關(guān)鍵字 interface 來定義接口(注意可選方法體的實現(xiàn))
interface MyInterface {
fun bar()
fun foo() {
// 可選的方法體
}
}
接口實現(xiàn)
class Child : MyInterface {
override fun bar() {
// 方法體
}
//foo() 根據(jù)情況選擇實現(xiàn)
}
擴(kuò)展
概念:
能夠擴(kuò)展一個類的新功能而無需繼承該類或使用像裝飾者這樣的任何類型的設(shè)計模式。 這通過叫做擴(kuò)展的特殊聲明完成,簡單說就是這個對象的功能不能滿足我,我用對象.xxxx(){}給你新添加一個屬性來滿足我,然后整個項目都能用這個屬性
class C {
fun foo() { println("member") }
}
fun C.foo() { println("extension")
}
調(diào)用 C().foo(1) 將輸出 "extension"。
實例(MutableList是系統(tǒng)級別):
fun MutableList<Int>.swap(index1: Int, index2: Int) {//swap(x,x)是不滿足當(dāng)前應(yīng)用的一個自定義擴(kuò)充
val tmp = this[index1] // “this”對應(yīng)該列表
this[index1] = this[index2]
this[index2] = tmp
}
然后再項目里的任何用到的類里都能直接調(diào)用,而不是之前java各種單利,各種xxUtils.swap(x,x),都不需要
val l = mutableListOf(1, 2, 3)
l.swap(0, 2) // “swap()”內(nèi)部的“this”得到“l(fā)”的值
擴(kuò)展的作用域
package vodjk.com.utils
import android.app.Activity
fun Activity.toask(des: String) {
}
fun MutableList<Int>.swap(index1: Int, index2: Int) {
}
依此類推各種Activity.swap(xxx),各種Toask.swap(xxx),各種擴(kuò)充,是不是很方便
密封類
特別類型java里的工廠模式
package com.xingen.kotlin
fun main(str: Array<String>) {
test( BaseClass.Test1() )
test( BaseClass.Test2() )
test( BaseClass.Test3 )
}
/**
* 使用when表達(dá)式
*/
fun test(instance: BaseClass)=when(instance){
is BaseClass.Test1-> instance.test()
is BaseClass.Test2-> instance.test()
is BaseClass.Test3->instance.test()
}
/**
*
* sealed修飾符修飾密封類。
*
* 密封類內(nèi)部含有多個子類。
*/
sealed class BaseClass {
class Test1 : BaseClass() {
override fun test() {
println("Test1實例")
}
}
class Test2 : BaseClass() {
override fun test() {
println("Test2實例")
}
}
object Test3 : BaseClass() {
override fun test() {
println("Test3實例")
}
}
open fun test() {
println("BaseClass實例")
}
}
空安全
Kotlin 的類型系統(tǒng)旨在消除來自代碼空引用的危險,也稱為《十億美元的錯誤》哈哈
允許為空
如果要允許為空,我們可以聲明一個變量為可空字符串,寫作 String?:
var b: String? = "abc"
b = null // ok
val l = a.length(對于這句當(dāng)b=null時不會報NPE,但是這樣寫不是安全的)
解決方案1
if (b != null && b.length > 0) {
print("String of length ${b.length}")
} else {
print("Empty string")
}
解決方案2 kotlin的安全調(diào)用
b?.length(是安全調(diào)用操作符,寫作 ?.)
如果 b 非空,就返回 b.length,否則返回 null,這個表達(dá)式的類型是 Int?。
bob?.department?.head?.name
假如一個對象為空,能不能忽略不計或者跳過呢 Elvis 操作符 就來了
java模式的寫法是
val l: Int = if (b != null) b.length else -1
Elvis 操作符表達(dá),寫作 ?:
val l = b?.length ?: -1
委托
類委托
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
Derived(b).print() // 輸出 10
}
Derived 的超類型列表中的 by-子句表示 b 將會在 Derived 中內(nèi)部存儲。 并且編譯器將生成轉(zhuǎn)發(fā)給 b 的所有 Base 的方法。
請注意,覆蓋會以你所期望的方式工作:編譯器會使用你的 override 實現(xiàn)取代委托對象中的實現(xiàn)。如果我們?yōu)?Derived 添加 override fun print() { print("abc") },該程序會輸出“abc”而不是“10”。
屬性委托
延遲屬性(lazy properties): 其值只在首次訪問時計算,
可觀察屬性(observable properties): 監(jiān)聽器會收到有關(guān)此屬性變更的通知
//初始化
var index: Int by Delegates.observable(1) {
pro, oldValue, newValue ->
if (newValue == 20) {
toast("關(guān)閉")
Log.e("Test", oldValue.toString() + "關(guān)閉" + newValue)
} else {
Log.e("Test", oldValue.toString() + "開啟" + newValue)
}
}
//賦值
for (i in 0..40) {index = i}
把多個屬性儲存在一個映射(map)中,而不是每個存在單獨的字段中。
http://www.runoob.com/kotlin/kotlin-delegated.html
Lambda 表達(dá)式語法
lambda 表達(dá)式總是被大括號括著, 完整語法形式的參數(shù)聲明放在括號內(nèi),并有可選的類型標(biāo)注, 函數(shù)體跟在一個 -> 符號之后。如果推斷出的該 lambda 的返回類型不是 Unit,那么該 lambda 主體中的最后一個(或可能是單個)表達(dá)式會視為返回值。
val sum: (Int, Int) -> Int = { x, y -> x + y }
lambda 表達(dá)式語法缺少的一個東西是指定函數(shù)的返回類型的能力,所以匿名函數(shù)就出來了
匿名函數(shù)看起來非常像一個常規(guī)函數(shù)聲明,除了其名稱省略了。其函數(shù)體可以是表達(dá)式(如上所示)或代碼塊:
fun(x: Int, y: Int): Int {
return x + y
}
this限定詞
為了表示當(dāng)前的 接收者 我們使用 this 表達(dá)式
1:在類的成員中,this 指的是該類的當(dāng)前對象
2:在擴(kuò)展函數(shù)或者帶接收者的函數(shù)字面值中, this 表示在點左側(cè)傳遞的 接收者 參數(shù)。
3:如果 this 沒有限定符,它指的是最內(nèi)層的包含它的作用域。要引用其他作用域中的 this,請使用 標(biāo)簽限定符:
class A { // 隱式標(biāo)簽 @A
inner class B { // 隱式標(biāo)簽 @B
fun Int.foo() { // 隱式標(biāo)簽 @foo
val a = this@A // A 的 this
val b = this@B // B 的 this
val c = this // foo() 的接收者,一個 Int
val c1 = this@foo // foo() 的接收者,一個 Int
val funLit = lambda@ fun String.() {
val d = this // funLit 的接收者
}
val funLit2 = { s: String ->
// foo() 的接收者,因為它包含的 lambda 表達(dá)式
// 沒有任何接收者
val d1 = this
}
}
}
}
Kotlin 中創(chuàng)建類似 Java 的靜態(tài)方法
java static 的寫法
public class Utils {
public static boolean isEmpty(String string){
return string != null && string.length() == 0;
}
public static boolean isWeakEmpty(String string){
return isEmpty(string) && string.trim().length() == 0;
}
}
用法:
boolean result = Utils.isEmpty(name);
kotlin 的寫法
//使用object關(guān)鍵字創(chuàng)建作用類
object Utilss {
fun isEmpty(string: String?): Boolean {
return string != null && string.length == 0
}
fun isWeakEmpty(string: String): Boolean {
return isEmpty(string) && string.trim { it <= ' ' }.length == 0
}
}
//調(diào)用方式
println(Utils.isEmpty(username))
let、with、apply、also、run
