版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/heming9174/article/details/75312560
感觉学习进度越来越慢了,一个新的知识点需要学习好久.
22.
Kotlin的扩展方法和扩展属性
可以自定义方法和运算符啊
可以理解为 加强版的Utils
只需要遵循
fun X.Y():Z{}
X为类名
Y为自定义的扩展方法名称,可以进行传参
Z为扩展方法的返回值,如果返回值为Unit,可以省略
举个栗子
fun main(args: Array<String>) {
//String肯定没有这种方法
//拓展方法类似于工具类
//当然在Kotlin内还有操作符进行扩展
"0123456789".typewriter()
println("abc"*6)
}
//fun X(String).Y()(typewrite()):Z{}(因为没有返回值,所以省略)
fun String.typewriter(){
//逐字打印
var arr = this.toCharArray()
var stringBuffer = StringBuffer()
for (i in 0 until arr.size){
stringBuffer.append(arr[i].toString())
println(stringBuffer.toString())
}
}
//和上面的一样,只不过是有参数和返回值
operator fun String.times(int:Int):String{
var sb = StringBuffer()
for (i in 0 until int){
sb.append(this)
}
return sb.toString()
}
都是String添加扩展方法,第一个是普通的扩展方法,第二个是 操作符扩展方法
扩展属性的话,没什么意义,其实就是setter/getter
var String.a:String
set(value) {
}
get() = "abc"
val String.b:String
get()="aaa"
fun main(args: Array<String>) {
"aaa".a = "111"
"aaa".a
"bbb".b
}
只想说一句,我次奥,居然还有这种操作.
Java调用
原本以为又是添加注解,没想到居然不是
Java调用类似于添加了注解的静态方法,直接类名点方法名即可.
其中第一个参数receiver及对应的X的值.也就是Kotlin里面写的扩展方法的this
public static void main(String[] args) {
Test3Kt.times("abc",4);
Test3Kt.typewriter("0123456789");
}
23.
Kotlin的属性代理
话说,之前有记录Kotlin的懒加载
val x by lazy {
"hello"
}
比如这样,只有当变量x在使用的时候才进行加载,赋值为”hello”.
其中lazy就是代理
点下那个by,发现跳转的方法是:
@kotlin.internal.InlineOnly
public inline operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
也就是变量x在被调用的是,调用getValue(),赋值value即”hello”
创建一个类,把这个方法拷过来,创建属于自己的代理.
发现由于var是 读写权限,不仅仅需要getValue(),同时还需要setValue()
class OK {
private var str :String ?= null
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
println("我调用了OK的getValue,是通过${property.name} 调用的")
return str?:""
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, str: String) {
println("我调用了OK()的setValue方法,是通过${property.name}调用的,设置值为:$str")
this.str = str
}
}
class Normal {
//val 只读
val read by OK()
//var 读写,所以必须要实现setValue()方法
var write by OK()
}
fun main(args: Array<String>) {
val n = Normal()
//输出打印的是X().getValue()的值
println(n.read)
//未对write赋值,输出打印出来的还是OK().getValue()值,即""
println(n.write)
//进行赋值,会自动调用OK().setValue()方法
n.write = "kotlin"
//这次返回的即赋值后的getValue()
println(n.write)
}
- 自定义代理.val只读,只需要getValue(),var读写,还需要setValue().
- 代理类,setValue()需要3个参数,需要添加一个参数进行设置
- 创建的代理类,自定义了一个内部变量str,默认为null,在getValue()内当为null,返回”“,?:是Elvis操作符
- 当进行赋值时,就会自动调用代理类的setValue()方法
这是输出结果:
我调用了OK的getValue,是通过read 调用的
我调用了OK的getValue,是通过write 调用的
我调用了OK()的setValue方法,是通过write调用的,设置值为:kotlin
我调用了OK的getValue,是通过write 调用的
kotlin
最后打印结果,因为调用n.read和n.write是默认调用OK().getValue(),即为””
对n.write进行赋值,会自动调用OK().setValue()
再次调用n.write,这次str的值为刚刚赋的值,即kotlin