更多问答 >>
-
2019-11-26 00:12
-
每日一问 | Activity启动流程中,大部分都是用Binder通讯,为啥跟Zygote通信的时候要用socket呢?
2019-11-30 20:49 -
2019-12-04 00:18
-
每日一问 Android 签名机制 v1 v2 v3 , 卧槽都 v3 了?
2019-12-09 23:52 -
2019-12-15 23:55
-
每日一问 | Kotlin 中不需要写“ ; ”,但是有个场景意外?
2019-11-22 00:12 -
每日一问 | 控件不都是矩形么?遇到多边形,这个怎么绘制,事件分发怎么处理嘞?
2019-11-13 01:08 -
2019-11-08 23:06
-
2019-11-03 23:50
-
2019-10-28 21:13
扩展方法,它是怎么实现的呢?
先来定义一个:然后通过Tools -> Kotlin -> Show Kotlin Bytecode -> Decompile 来查看反编译后的Java代码:
可以看到,我们定义的扩展方法
来看看调用的地方:first
,最终会变成一个静态的方法,方法的参数就是目标类对象。反编译之后:
emmm,调用扩展方法的地方,转成Java后看到的就跟调用静态方法没什么两样了,只是编译器帮我们传了参数而已。
扩展方法可以覆盖掉已有的方法吗?
不能,如果一个类的扩展方法跟已有的方法同名(同签名),那么在调用的时候,会优先调用类中的方法,并不会调用扩展方法(即使已经手动import);因为扩展方法跟现有方法同名(同签名)的话,在编译成class时,编译器并不知道你本次的调用究竟是想调用哪一个(只能当成是调用已有的方法),所以想要扩展方法生效,就不能跟目标类的现有方法重名(同签名)。有什么约束?
同一级包下不能有多个相同签名的扩展方法;但是包名不同,签名相同的扩展方法,可以通过导入指定的包来告诉编译器想使用哪一个。恭喜小缘收获迷哥一枚。
哈哈,什么
他要当你小弟
哈哈哈,不敢不敢,我才是小弟
需要会喊666的人不,我会
看了下,回答多数是讲原理的,我说下具体怎么做吧。
一般是在类的最前面定义,这样后面这里就可以用了 (这里获取context是封装个的一个公用的,一般项目都会有)
反之写在定义后面是不行的kotlin是表达式语言,表达式语言是什么意思呢?简单来说就是读起来像句子的语言。
在我们来说就是主谓宾这种固定顺序,主语就是要扩展的对象,谓语就是方法名,宾语就是参数。
不幸的是,在java里,int连对象都不是。
不是说其他的,就是说在java里不是对象的东西能不扩展就不扩展了,让它充当宾语。像问题中这种,12.dp(),它就不适合用来做扩展,为什么呢,读不通,而且你不知道12到底是什么。改成
12.px2dp
?发现也不通,12如果是px的话,就和方法中的px重复了。那么什么情况下int能用来做扩展呢,加减乘除:
那么题中的扩展就可以写成
主语是Resource或者是Context,api是由px转dp,这样就可以读通顺了。
要切记呀,不能图简洁消耗掉可读性,所有的表达式语言是同理的,读起来一定要成句。
返回值落了 ``` fun Resources.fromPx2dp(px: Int) :Int{ } ```
/**
(this表示这个int值)
kotlin中调用:12.dp(),java中调用:Util.dp(12) Util是创建的类名
kotlin的扩展方法很方便,建议多使用,能省很多代码
1.还是相当于Util.dp(12),只不过换了一种写法
2.如果系统已有这种方法,调用自己的需要加包名和类名3.如果非要说约束的话,必须是Int才能调用这个方法回答的不对的话,请大神指正。
扩展方法:
定义方式:fun 类名.方法名():返回类型{...}实际实现方式用java调用一下就知道怎么回事了,实际上就是工具类然后第一个参数默认的是调用者实体如12.dp实际上类似xxxUtil.dp(12)Java怎么调Kotlin的扩展函数么?
文件名Util.方法名(调用者,其他参数) 大概的调用方式是这样