Hello,本次More Time 带来 Kotlin 超好用的特性——扩展函数 。
扩展函数的意思就是可以给一个类加上一个新函数。
有人说:那直接在类里面加呗。
有种东西叫做别人的代码,只能用,不能改。
有人说:继承不就是了么?
不让继承呢?Java里 final
类就不让继承,kotlin的类如果不加 open
也不让继承。
并且写一个类继承并没有什么用,父类并不能转成子类。
所以诞生了一个新事物:util类。关于util类可以看看 lombok 的 UtilityClass 。
总之就是一堆静态函数的类,举个最常用的,打印数组。
public static void main(String[] args) {
int[] a = {1, 2, 3};
System.out.println(a);
System.out.println(Arrays.toString(a));
}
输出
[I@74a14482
[1, 2, 3]
里面的 Arrays就是工具类,全是静态方法,都不能Arrays这个类都不能 new。
现在问题来了,我就是想输出一个数组,我不关心工具类。如果 a.toString()
不能带来一个能够打印的字符串,那么给个 a.toPrintableString()
都是可以接受的,但是多了一个 Arrays
就让人心情烦躁。
看看 kotlin 怎么做的
fun main() {
val a = intArrayOf(1, 2, 3)
println(a)
println(a.joinToString())
}
输出
[I@4b67cf4d
1, 2, 3
这就很人性。
有人会说:这只能说明 kotlin函数多,并不能说明扩展函数的好处。但是这个 joinToString()
这个方法也可以视为 int[]
的扩展方法
那么下面举一个实际业务的例子:
小王得写一个小模块,接收class A,然后 A -> B -> C -> D;ABCD全部都是小亦给的,小王不能改。
class A { }
class B { }
class C { }
class D { }
public class Main {
public static void main(String[] args) {
A a = new A();
// 开始你的表演
}
}
那 Java 里面 只能写 Util类了
class AU {
static B toB(A a) {
return new B();
}
}
class BU {
static C toC(B b) {
return new C();
}
}
class CU {
static D toD(C c) {
return new D();
}
}
然后看看如何生成这个 D
非常恐怖
D d = CU.toD(BU.toC(AU.toB(a)));
头都看昏了,所以一般也不会这么写,而是
B b = AU.toB(a);
C c = BU.toC(b);
D d = CU.toD(c);
勉强能忍,就是多打几行,增加了几个多余的变量。
但最佳的语法就是a.toB().toC().toD()
这种链式调用是最好的。
在 Java中,ABCD因为是其他人写的,固定了,不可以再加上 toB
这种方法。但是kotlin的扩展函数,可以给固定了的类加新函数,从而实现这个效果。
原理也非常简单,不是什么反射这种高级东西,就是编译的之后转成别的函数调用。
语法和定义函数一样, fun
开头。只不过给函数名前面加上类名。如上述例子 kotlin 的写法就是
class A {}
class B {}
class C {}
class D {}
fun main() {
fun A.toB() = B()
fun B.toC() = C()
fun C.toD() = D()
val a = A()
val d = a.toB().toC().toD()
}
如此简洁优雅,世界多么美好
总结:
Kotlin 的扩展函数可以很好的取代工具类甚至更强。
就算使用了 Spring,有了单例,依赖注入,有的类还是摆脱不了工具类这个事实,想写成一行就得 D d = CU.toD(BU.toC(AU.toB(a)));
这种形式。
扩展函数不仅可以在当前文件写,还可以从别的文件引入
通过扩展函数,代码从 工具.做啥(我,附加信息)
变成了 我.做啥(附加信息)
这种符合人类思维的方式,实在是开发节省时间的良药。
欢迎访问