Kotlin------類和對象(二)

get/set方法

聲明一個屬性的完整語法是安全

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

PropertyType、property_initializer、getter、setter均是可選的元素,這裏再強調下,val類型變量爲可讀變量,因此只擁有get方法,而var類型則有get/set方法。這裏直接自定義Student類的birthday的get/set方法ide

class Student {
    ...
    var age: Int?//自定義get/set方法
        get() = field //使用備用字段自定義get/set方法
        set(value) {//value是自定義的變量名,名字能夠隨便起
            age = value
        }
    ...
}

接口

Kotlin 的接口與 Java 8 相似,既包含抽象方法的聲明,也包含實現。與抽象類不一樣的是,接口沒法保存狀態。它能夠有屬性但必須聲明爲抽象或提供訪問器實現。spa

public interface SomeInterface{
    var value:String //默認abstract

    fun reading() // 未實現

    fun writing(){  //已實現
        // do nothing
    }
}
class MyImpl:SomeInterface{
    override var value: String = "jason" //重載屬性
    override fun reading() {
        // 方法體
    }  
}

 

枚舉

枚舉類的最基本的用法是實現類型安全的枚舉code

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

每一個枚舉常量都是一個對象。枚舉常量用逗號分隔。對象

使用:blog

 var color:Color=Color.BLUE
println(Color.values()) println(Color.valueOf(
"RED")) println(color.name) println(color.ordinal)//返回下標

委託

委託模式是一個頗有用的模式,它能夠用來從類中抽取出主要負責的部分。委託模式是Kotlin原生支持的,因此它避免了咱們須要去調用委託對象。委託者只須要指定實現的接口的實例。繼承

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 的對象實例內部,並且編譯器將會生成繼承自 Base 接口的全部方法, 並將調用轉發給 b。接口

 委託屬性

kotlin經過屬性委託的方式,爲咱們實現了一些經常使用的功能,包括:get

  1. 延遲屬性(lazy properties): 其值只在首次訪問時計算,
  2. 可觀察屬性(observable properties): 監聽器會收到有關此屬性變動的通知,
  3. 把多個屬性儲存在一個映射(map)中,而不是每一個存在單獨的字段中。

延遲屬性

延遲屬性咱們應該不陌生,也就是一般說的懶漢。編譯器

//標準委託 延遲屬性
    val lazyValue : String by lazy {
           Log.d("m", "只執行1次")
           "value"
    }
 println(lazyValue)
 println(lazyValue)

 //執行
 D/m: 只執行1次
 I/System.out: value
 I/System.out: value

可觀察屬性 Observable

Delegates.observable() 接受兩個參數:初始值和修改時處理程序(handler)。 每當咱們給 屬性賦值時會調用該處理程序(在賦值後執行)。它有三個參數:被賦值的屬性、舊值和新 值:

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}
//可觀察屬性 Observable
   val user = User()
   user.name = "first"
   user.name = "second"
//執行結果
I/System.out: <no name> -> first
I/System.out: first -> second

把屬性儲存在映射中

一個常見的用例是在一個映射(map)裏存儲屬性的值。 這常常出如今像解析 JSON 或者作其餘「動態」事情的應用中。 在這種狀況下,你可使用映射實例自身做爲委託來實現委託屬性。

class MapUser(val map: Map<String, Any?>) {

    val name: String by map
    val age: Int     by map
}
//把屬性儲存在映射
  val userMap = MapUser(mapOf(
        "name" to "小七",
        "age"  to 21
   ))
  println(userMap.name)
   println(userMap.age)
//執行結果
I/System.out: 小七
I/System.out: 21
相關文章
相關標籤/搜索