1. 程式人生 > >Kotlin初階(2)

Kotlin初階(2)

Kotlin初階(2)

第一篇入口:Kotlin初階(2)

Kotlin初階易錯知識點

9、數字定義(可以用"_"來區別很長的數字)

    //使用下劃線使數字常量更易讀
    val oneMillion = 1_000_000
    val creditCardNumber = 1234_5678_9012_3456L
    val socialSecurityNumber = 999_99_9999L
    val hexBytes = 0xFF_EC_DE_5E
    val bytes = 0b11010010_01101001_10010100_10010010
複製程式碼

10、for迴圈(極其方便)

fun forCircle
() { for (i in 1..5 step 1) { print(i) //輸出12345 } for (i in 5 downTo 1 step 1) { print(i) //輸出54321 } for (i in 1..5 step 2) { print(i) //輸出13 } for (i in 1 until 5 step 1) { print
(i) //輸出1234,沒有5 等同於[1,5) } } 複製程式碼

11、型別替代(typealias)

typealias f = Foo//型別替代(f代表新的名詞,Foo代表需要另起名字的物件名,比如,Foo全名為:尼古拉斯.凱奇.趙四,那麼f可以叫做趙四,哪裡需要這麼高大上的名稱)
複製程式碼

12、is和!is

    fun getStringLength(obj: Any): Int? {
        if (obj !is String) {
            return null
        }
        //此時obj已經自動轉化為string型別
        return
obj.length } 複製程式碼

13、lambda表示式使用之一

//limbda表示式
val sumLambda: (Int, Int) -> Int = { x, y -> x + y }//xy是入參,x+y是返回值
複製程式碼

14、長度可變的入參(關鍵字:vararg)

    //可變長度入參
    fun sum5(vararg v: Int): Int {
        var sum = 0
        for (vt in v) {
            sum += vt
        }
        return sum
    }
複製程式碼

15、類相關(主建構函式,次建構函式,init方法,預設引數,變數的get和set方法,super父類方法,重寫父類方法,共有函式,私有函式)

class Runoob constructor(name1: String = "jack", psd1: String = "123456") {//預設引數
//主構造器中不能包含任何程式碼,初始化程式碼可以放在初始化程式碼段中,初始化程式碼段使用 init 關鍵字作為字首
init {
    println("name : $name1, psd : $psd1")
//    name = ""//這裡連name常量都沒有定義,所以不能夠進行賦值
}

    constructor(name: String, psd: String, addr: String) : this(name, psd) {
        this.name = name
        this.psd = psd
    }

    //次建構函式
    constructor(name: String, psd: String, age: Int) : this(name, psd) {
    }

    var nickName = name1
        get() {
            return nickName
        }

    var name: String
        get() {
            return name.toUpperCase()
        }
        set(value) {
            name = value
        }
    var psd: String = ""
        private set
        get() {
            return psd + "@"
        }
}
複製程式碼

16、interface的方法體是否實現是可選的。屬性也是抽象的,需要實現類重新賦值。

interface BaseView {
	var mNickName: String//抽象的屬性
    fun walk() {//方法體是否實現是可選的
        println("BaseView,walk!!!")
    }

    fun yeal() {}//
}
複製程式碼

17、密封類

//密封類
sealed class Expr//相當於列舉的擴充套件

data class Const(val number: Double) : Expr()//這裡只有另外一個double的狀態入參
data class Sum(val e1: Expr, val e2: Expr) : Expr()//這個密封類裡面就有兩個Expr的狀態入參
object NotANumber : Expr()

fun eval(expr: Expr): Double = when (expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
    //因為已經覆蓋了所以的情況,就不需要else子句了
}
複製程式碼

18、列舉

    Color.BLACK.name
    enumValues<Color>().size
    enumValues<Color>().get(0)
    enumValues<Color>().plus(Color.WHITE)
    enumValues<Color>().iterator()
    enumValueOf<Color>(Color.WHITE.toString())
複製程式碼

19、list和Comparable

fun <T : Comparable<T>> sort(list: List<T>) {
}
    sort(listOf(1, 2, 3)) // OK。Int 是 Comparable<Int> 的子型別
    // 錯誤:HashMap<Int, String> 不是 Comparable<HashMap<Int, String>> 的子型別
//    sort(listOf(HashMap<Int, String>()))
複製程式碼

20、object物件

    val site = object {
        var name = "jack"
        var url = "www.tansu.com"
    }
複製程式碼

21、委託類,委託物件(通過關鍵字 by 建立)

interface MyBase {
    fun bark()
//    fun bak()
}

class BaseImpl(val x: Int) : MyBase {
    fun bak() {}
    override fun bark() {
        println("x:$x")
    }
}

// 通過關鍵字 by 建立 委託類
class Deried(b: MyBase) : MyBase by b

fun test3() {
    var baseImpl = BaseImpl(10)
    Deried(baseImpl).bark()
    baseImpl.bak()
//    Deried(baseImpl).bak()//無法訪問到非interface定義的方法
}

// 定義包含屬性委託的類
class Example {
    var p: String by Delegate()
    //說明:如果p是var的話,那麼委託類需要有getValue和setValue兩個方法(因為此時是可變的變數,需要由set方法)
    //說明:如果p是val的話,那麼委託類只需要有getValue方法即可,另外一個可以不要求(此時為不可變常量,不需要set值進去)
}

// 委託的類
class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, 這裡委託了 ${property.name} 屬性"//這裡name為p
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef${property.name} 屬性賦值為 $value")//value為設定進來的值
    }
}

fun test4() {
    val e = Example()
    println(e.p)     // 訪問該屬性,呼叫 getValue() 函式

    e.p = "Runoob"   // 呼叫 setValue() 函式
    println(e.p)
//    [email protected], 這裡委託了 p 屬性
//    [email protected] 的 p 屬性賦值為 Runoob
//    [email protected], 這裡委託了 p 屬性
}
複製程式碼

21、監聽類值的變化

class User {
    var name: String by Delegates.observable("初始值") { prop, old, new ->
        println("舊值:$old -> 新值:$new. prop:$prop")
    }
}
    val user = User()
    user.name = "第一次賦值"
    user.name = "第二次賦值"
//    舊值:初始值 -> 新值:第一次賦值
//    舊值:第一次賦值 -> 新值:第二次賦值
複製程式碼

22、map

//把屬性儲存在對映中
class MyWebSite(val map: Map<String, Any?>) {
    val name: String by map
    val url: String  by map
}
使用
    var myWebSite = MyWebSite(mapOf("name" to "jack", "url" to "www.baidu.com"))
    myWebSite.name
    myWebSite.url
    //結果讀取出來
複製程式碼

23、其它

class Foo {
    var notNullBar: String by Delegates.notNull<String>()
}
使用
    var foo = Foo()
    foo.notNullBar = "bar"
    println(foo.notNullBar)
複製程式碼

第一篇入口:Kotlin初階(2)