Kotlin 对象枚举委托
Posted Lucky_William
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 对象枚举委托相关的知识,希望对你有一定的参考价值。
目录
一、Kotlin 对象
1. kotlin 伴生对象
class Demo
val field: String = "demo field"
// kotlin 定义伴生对象
companion object
// kotlin 定义常量
const val KEY_NAME = "key_name"
// kotlin 模拟静态方法
@JvmStatic // 加注解实现和 java 中使用静态方法相同效果
fun method()
println("invoke companion method")
fun main()
// kotlin 可以使用外部类的类名直接调用伴生对象的属性或方法
Demo.KEY_NAME
Demo.method()
2. kotlin 对象和单例模式
fun main()
// 使用 object 声明对象表达式
val runnable = object : Runnable
override fun run()
println("run in Runnable")
// 同上,lambda 简写形式
val runnable2 = Runnable
println("run in Runnable lambda")
// 使用对象表达式
Thread(runnable).start()
Thread(runnable2).start()
// 调用单例类的属性和方法
println(DemoManager.field)
DemoManager.method()
/**
* 使用 object 定义单例类
*/
object DemoManager
var field = "string value"
fun method()
println("invoke method")
二、Kotlin 枚举
1. kotlin 定义枚举
enum class Week(val text: String = "")
Monday("星期一"),
Tuesday("星期二"),
Wednesday("星期三"),
Thursday("星期四"),
Friday("星期五"),
Saturday("星期六"),
Sunday("星期日")
2. kotlin 使用枚举
fun main()
// 构造枚举
val tuesday = Week.valueOf("Tuesday")
// 访问枚举常量的名称,与在其枚举声明中声明的完全相同。
println(tuesday.name) // Tuesday
// 返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量被分配零序数)
println(tuesday.ordinal) // 1
// 返回此枚举类型的常量的数组
println(Week.values().contentToString()) // [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
// 访问枚举
val week: Week = Week.Monday
when (week)
Week.Monday -> println(week.name) // Monday
Week.Tuesday -> println(week.name)
Week.Wednesday -> println(week.name)
Week.Thursday -> println(week.name)
Week.Friday -> println(week.name)
Week.Saturday -> println(week.name)
Week.Sunday -> println(week.name)
三、Kotlin 委托
1. kotlin 类委托
/**
* 定义接口
*/
interface Factory
fun produce()
/**
* 美食工厂,实现工厂的方法
*/
class FoodFactory : Factory
override fun produce()
println("生产美食")
/**
* Agent1 实现了 Factory 接口,但委托给 FoodFactory 去实现
*/
class Agent1(factory: FoodFactory) : Factory by factory
/**
* Agent2 实现了 Factory 接口,但委托给 FoodFactory 去实现,重写了接口定义的方法
*/
class Agent2 : Factory by FoodFactory()
override fun produce()
println("Agent2 自己 生产美食")
fun main()
// 类委托
val agent1 = Agent1(FoodFactory())
agent1.produce() // 生产美食
val agent2 = Agent2()
agent2.produce() // Agent2 自己 生产美食
2. kotlin 属性委托
提供和 ReadOnlyProperty 或 ReadWriteProperty 接口相同签名的方法即可实现属性委托
/**
* 定义属性委托
*/
class FieldDemo
var name: String by FieldDelegate()
/**
* 属性委托类,提供和 ReadOnlyProperty 或 ReadWriteProperty 接口相同签名的方法即可实现属性委托
*/
class FieldDelegate
private var fieldValue = "default str"
operator fun getValue(thisRef: FieldDemo, property: KProperty<*>): String
println("获取 $thisRef.javaClass.simpleName 的属性 $property.name 值")
return fieldValue
operator fun setValue(thisRef: FieldDemo, property: KProperty<*>, value: String)
println("设置 $thisRef.javaClass.simpleName 的属性 $property.name 值:$value")
fieldValue = value
fun main()
// 属性委托
val fieldDemo = FieldDemo()
fieldDemo.name = "test field delegate" // 设置 FieldDemo 的属性 name 值:test field delegate
println(fieldDemo.name) // 获取 FieldDemo 的属性 name 值
3. kotlin Map 委托
- kotlin 在 MapAccessors 类中给 Map 定义了和 ReadOnlyProperty 接口相同签名的方法,可以用于只读属性的委托。
- kotlin 在 MapAccessors 类中给 MutableMap 定义了和 ReadWriteProperty 接口相同签名的方法,可以用于读写属性的委托。
/**
* 只读属性可以委托给 Map
* 类只需要对外暴露 map 即可
*/
class DelegateMap(val map: Map<String, Any?>)
val key1: Int by map
val key2: String by map
val key3: Boolean by map
/**
* 读写属性可以委托给 MutableMap
* 类只需要对外暴露 map 即可
*/
class DelegateMutableMap(val map: MutableMap<String, Any?>)
var key1: Int by map
var key2: String by map
var key3: Boolean by map
fun main()
// 只读属性对外暴露 Map
val delegate1 = DelegateMap(mapOf("key1" to 1, "key2" to "str", "key3" to true))
// 相当于调用 ReadOnlyProperty 的 getValue 方法
println(delegate1.key1)
println(delegate1.key2)
println(delegate1.key3)
val map = delegate1.map
println(map["key1"])
println(map["key2"])
println(map["key3"])
// 读写属性对外暴露 MutableMap
val delegate2 = DelegateMutableMap(mutableMapOf())
// 相当于调用 ReadWriteProperty 的 setValue 方法
delegate2.key1 = 100
delegate2.key2 = "key2 value"
delegate2.key3 = false
val mutableMap = delegate2.map
println(mutableMap["key1"])
println(mutableMap["key2"])
println(mutableMap["key3"])
4. kotlin 延迟属性
- 当延迟属性被访问的时候才会执行 lambda 表达式初始化值
- 只会执行一次 lambda 表达式,随后会获取第一次的值直接返回
// 延迟属性:只会获取一次 lambda 表达式的值,后续会使用第一次获取的值直接返回
val lazyField: String by lazy
println("执行 lambda 表达式")
"this is a lazy field"
// 传入策略,使用锁用于确保只有单个线程可以初始化Lazy实例。
val lazyField2: String by lazy(LazyThreadSafetyMode.SYNCHRONIZED)
"this is a lazy field"
fun main()
// 只会打印一次 "执行 lambda 表达式"
println(lazyField)
println(lazyField)
5. kotlin 属性监听
/**
* 属性监听,总是能赋值成功
*/
var observerField1: String by Delegates.observable("default") property, oldValue, newValue ->
println("$property 的 oldValue: $oldValue, newValue: $newValue")
/**
* 属性监听,符合条件 新值大于 0,才能成功赋值
*/
var observerField2: Int by Delegates.vetoable(0) property, oldValue, newValue ->
println("$property 的 oldValue: $oldValue, newValue: $newValue")
newValue > 0
fun main()
observerField1 = "set new value" // 打印:kotlin.String 的 oldValue: default, newValue: set new value
observerField2 = 1 // 打印:kotlin.Int 的 oldValue: 0, newValue: 1
observerField2 = -1 // 打印:kotlin.Int 的 oldValue: 1, newValue: -1,此处会设置失败,需要大于0才能设置成功
println(observerField2) // 打印:1
附 Github 源码
以上是关于Kotlin 对象枚举委托的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin常用的 Kotlin 类 ② ( 枚举类 | 枚举类定义函数 | 密封类 )