泛型
//实现类似apply函数功能
//Any表示泛型具体的类型上限
fun <T : Any> T.build(block: T.() -> Unit): T {
block()
return this
}
fun main() {
val sb = StringBuilder()
sb.build {
append("123")
append("wechat")
}
println(sb) //123wechat
}
泛型实化
//需要同时使用inline(内联函数)和reified关键字
//直接返回当前指定泛型的实际类型T::class:java
inline fun <reified T> getGenericType() = T::class.java
//应用: 重写startActivity函数
//startActivity<myActivity>(context) { putExtra("param1", "data") }
inline fun <reified T> startActivity(
context: Context,
block: Intent.() -> Unit
) {
val intent = Intent(context, T::class.java)
intent.block()
context.startActivity(intent)
}
fun main() {
println(getGenericType<String>())
//class java.lang.String
println(getGenericType<Int>())
//class java.lang.Integer
}
类委托和委托属性
委托是一种设计模式,它的基本理念是:操作对象自己不会去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理。
类委托
将一个类的具体实现委托给另一个类去完成。例如,利用helperSet对象去实现MySet类中的功能:
class MySet<T>(val helperSet: HashSet<T>) : Set<T> {
override val size: Int
get() = helperSet.size
override fun contains(element: T) = helperSet.contains(element)
override fun containsAll(elements: Collection<T>) = helperSet.containsAll(elements)
override fun isEmpty() = helperSet.isEmpty()
override fun iterator() = helperSet.iterator()
}
使用场景:让大部分的方法实现调用辅助对象中的方法,少部分的方法实现由自己来重写,甚至加入一些自己独有的方法,那么MySet就会成为一个全新的数据结构类,这就是委托模式的意义所在。 语法糖: Kotlin中委托使用的关键字是by,我们只需要在接口声明的后面使用by关键字,再接上受委托的辅助对象,就可以免去之前所写的一大堆模板式的代码了。如果我们要对某个方法进行重新实现,只需要单独重写那一个方法就可以了,其他的方法仍然可以享受类委托所带来的便利。 MySet就成为了一个全新的数据结构类,它不仅拥有HashSet的全部功能,而且还能打印helloWorld(),这就是Kotlin的类委托所能实现的功能。
class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {
fun helloWorld() = println("hello world")
}
属性委托
类委托的核心思想是将一个类的具体实现委托给另一个类去完成,而委托属性的核心思想是将一个属性(字段)的具体实现委托给另一个类去完成。
class MyClass {
//表示将p属性实现交给Delegate类完成
//x = p 会自动调用Delegate类中的getValue()方法
//p = x 会自动调用Delegate类中的setValue()方法
var p by Delegate()
}
class Delegate {
var propValue: Any? = null
//第一个参数表示可以在什么类中使用委托功能
//KProperty<*>是Kotlin中的一个属性操作类,
//可用于获取各种属性相关的值,
//在当前场景下用不着,但是必须在方法参数上进行声明。
//<*>表示不知道或者不关心泛型的具体类型,只是为了通过编译
operator fun getValue(myClass: MyClass, kprop: KProperty<*>): Any? {
return propValue
}
operator fun setValue(myClass: MyClass, kprop: KProperty<*>, value: Any?) {
propValue = value
}
}
实现lazy懒加载函数
class Later<T>(val block: () -> T) {
var value: Any? = null
operator fun getValue(any: Any?, prop: KProperty<*>): T {
if (value == null) {
value = block()
}
return value as T
}
}
fun <T> later(block: () -> T) = Later(block)
fun main() {
//lambda函数只会执行一次
val p by later { "later string" }
println(p)
}