get/set方法
聲明一個屬性的完整語法是
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
PropertyType、property_initializer、getter、setter均是可選的元素,這里再強調(diào)下,val類型變量為可讀變量,所以只擁有g(shù)et方法,而var類型則有g(shù)et/set方法。這里直接自定義Student類的birthday的get/set方法
class Student {
...
var age: Int?//自定義get/set方法
get() = field //使用備用字段自定義get/set方法
set(value) {//value是自定義的變量名,名字可以隨便起
age = value
}
...
}
接口
Kotlin 的接口與 Java 8 類似,既包含抽象方法的聲明,也包含實現(xiàn)。與抽象類不同的是,接口無法保存狀態(tài)。它可以有屬性但必須聲明為抽象或提供訪問器實現(xiàn)。
public interface SomeInterface{
var value:String //默認abstract
fun reading() // 未實現(xiàn)
fun writing(){ //已實現(xiàn)
// do nothing
}
}
class MyImpl:SomeInterface{
override var value: String = "jason" //重載屬性
override fun reading() {
// 方法體
}
}
枚舉
枚舉類的最基本的用法是實現(xiàn)類型安全的枚舉
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
每個枚舉常量都是一個對象。枚舉常量用逗號分隔。
使用:
var color:Color=Color.BLUE
println(Color.values())
println(Color.valueOf("RED"))
println(color.name)
println(color.ordinal)//返回下標
委托
委托模式是一個很有用的模式,它可以用來從類中抽取出主要負責的部分。委托模式是Kotlin原生支持的,所以它避免了我們需要去調(diào)用委托對象。委托者只需要指定實現(xiàn)的接口的實例。
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)部,而且編譯器將會生成繼承自 Base 接口的所有方法, 并將調(diào)用轉(zhuǎn)發(fā)給 b。
委托屬性
kotlin通過屬性委托的方式,為我們實現(xiàn)了一些常用的功能,包括:
延遲屬性(lazy properties): 其值只在首次訪問時計算,
可觀察屬性(observable properties): 監(jiān)聽器會收到有關(guān)此屬性變更的通知,
把多個屬性儲存在一個映射(map)中,而不是每個存在單獨的字段中。
延遲屬性
延遲屬性我們應(yīng)該不陌生,也就是通常說的懶漢。
//標準委托 延遲屬性
val lazyValue : String by lazy {
Log.d("m", "只執(zhí)行1次")
"value"
}
println(lazyValue)
println(lazyValue)
//執(zhí)行
D/m: 只執(zhí)行1次
I/System.out: value
I/System.out: value
可觀察屬性 Observable
Delegates.observable() 接受兩個參數(shù):初始值和修改時處理程序(handler)。 每當我們給 屬性賦值時會調(diào)用該處理程序(在賦值后執(zhí)行)。它有三個參數(shù):被賦值的屬性、舊值和新 值:
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"
//執(zhí)行結(jié)果
I/System.out: <no name> -> first
I/System.out: first -> second
把屬性儲存在映射中
一個常見的用例是在一個映射(map)里存儲屬性的值。 這經(jīng)常出現(xiàn)在像解析 JSON 或者做其他“動態(tài)”事情的應(yīng)用中。 在這種情況下,你可以使用映射實例自身作為委托來實現(xiàn)委托屬性。
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)
//執(zhí)行結(jié)果
I/System.out: 小七
I/System.out: 21