聲明一個屬性的完整語法是安全
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
延遲屬性咱們應該不陌生,也就是一般說的懶漢。編譯器
//標準委託 延遲屬性 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
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