package com.example.providertest
import androidx.appcompat.app.ActionBarDrawerToggle
import kotlin.reflect.KProperty
**
* Kotlin中的泛型与委托
* 一般编程模式下,需要给任何一个变量指定一个具体的类型,而泛型允许在不指定具体类型的情况下进行编程,这样的程序拥有更加良好的扩展性
* 泛型主要有两种定义方式①定义泛型类②定义泛型方法
*
* 委托是一种设计模式,基本理念为:操作对象自己不会去处理某段逻辑,而是把工作委托给另外一个辅助对象去处理。java中对于委托没有语言层级的实现,C#有原生支持
* Kotlin也支持委托,分为类委托和属性委托
* 类委托:核心思想是将一个类的具体实现委托给另一个类去完成
* 委托属性:核心思想是将一个属性(字段)的具体实现委托给另一个类去完成
* */
/定义泛型类
class MyClass<T> {
fun method(param : T) : T{
return param
}
}
/在调用MyClass类和method方法的时候,可以将泛型指定为具体类型,
/这里将MyClass类泛型指定为Int类型,于是method方法就可以接收一个Int参数,并且返回值也变成了Int,
val myClass = MyClass<Int>()
val result = myClass.method(123)
/如果不想定义泛型类,只想定义泛型方法呢
class MyClass1 {
fun <T>method(param : T) : T{
return param
}
}
/调用方式也会相应改变
val myClass1 = MyClass1()
val result1 = myClass1.method<Int>(123) //由于类型推导机制其实可以省略<Int>
/kotlin还允许对泛型进行限制,比如将上界设置成number,那么只能传入Int Float Double等,如果此时传入字符串就会报错
class MyClass2 {
fun <T:Number>method(param : T) : T{
return param
}
}
/在默认情况下,所有的泛型都可以指定成可空类型的,因为不手动指定上界,泛型默认上界为Any?
/ 如果不想为空,可以将上界指定成Any。
/借助委托模式实现一个Set接口的实现类,
/ MySet的构造函数接收了一个HashSet参数,相当于一个辅助对象。然后Set接口中所有方法实现都没有自己去实现,
/ 而是调用了辅助对象中相应的方法区实现,这就是一种委托模式。
/但是这样有个卵子意义呢?还不如直接用辅助对象得了,这样说确实没错,但如果大部分都调用辅助对象,少部分方法自己重写,甚至加入独有方法,
/ 那么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()
}
/那如果接口中一大堆待实现呢?那不是写哭了,解决方案呢?java中没有,但kotlin中可以通过类委托功能来解决
/kotlin中委托使用的关键字是by,我们只需要在接口后面使用by关键字,在接上受委托的辅助对象,这样就可以免去之前一大堆模板式的代码了
class MySet1<T> (val helperSet: HashSet<T>) : Set<T> by helperSet{}
/MySet和MySet1效果一样的,但是借助类委托功能后,代码大幅简化,如果我们需要对某个方法重新实现,那么只要单独重写即可
/这里新增了helloWorld方法,并重写了isEmpty方法
class MySet2<T> (val helperSet: HashSet<T>) : Set<T> by helperSet{
fun helloWorld() = println("hello world")
override fun isEmpty(): Boolean {
return false
}
}
/属性委托的语法结构
class MyClass3 {
var p by Delegate()
}
/Delegate类的具体实现
class Delegate{
var propValue:Any? = null
/operator重载运算符关键字
/getValue接收两个参数,第一个用于声明Delegate类委托功能可以在哪个类中使用,
/ property: KProperty<*>是kotlin中的一个属性操作类,用于获取各种属性相关的值,这里用不到,
operator fun getValue(myClass3: MyClass3, property: KProperty<*>): Any? {
return propValue
}
operator fun setValue(myClass3: MyClass3, property: KProperty<*>, any: Any?) {
propValue = any
}
}
kotlin中的泛型与委托(类委托与属性委托)
最新推荐文章于 2023-12-16 22:43:05 发布