Java中所有的方法是需要定义在类中的,因此我们在封装一些工具方法的时候会先建一个Util的工具类,然后在里面添加我们需要用到的静态方法。
Kotlin中消除了这些静态工具类,可以用顶层方法来替代。
先来个示例:
1、新建个Kotlin文件(注意这里是文件不是Kotlin类),我们命名为String.kt。
2、在这个文件里定义一个函数来统计单词的字符数量:
fun letterCount(str: String): Int {
var count: Int = 0
for (char in str) {
if (char.isLetter()) count++
}
return count
}
反编译上面代码:
public static final int letterCount(@NotNull String str) {
Intrinsics.checkNotNullParameter(str, "str");
int count = 0;
String var4 = str;
...
}
通过反编译可以看到,该方法是public static final
,因此在其他地方都可以直接调用到。
3、顶层函数使用:Kotlin中可以直接使用,Java代码中需要编译后文件名StringKt
引用
Kotlin
fun main() {
val fruits = "apple"
println("letter count is : " + letterCount(fruits))
}
public static void main(String[] args) {
StringKt.letterCount("apple");
}
通过上面例子可以理解顶层方法就是直接定义在文件中的方法,无需依赖类存在,这应该就是为啥叫“顶层”的意思了。
4、顶层属性
顶层属性跟顶层函数一样,也是放在文件的顶层。
val mDayOfWeek = 7
fun letterCount(str: String): Int {
var count: Int = 0
for (char in str) {
if (char.isLetter()) count++
}
return count
}
反编译看下,变量是:private static final
来修饰的,但是自动生成了一个public
的get
方法可以拿到。
private static final int mDayOfWeek = 7;
public static final int getMDayOfWeek() {
return mDayOfWeek;
}
如果想直接定义一个public的变量呢?可以用const
关键字,例如
const val QQ_URL = "http://xx.com"
看下反编译的内容:
public static final String QQ_URL = "http://xx.com";
顶层属性的使用:Kotlin中可以直接使用,Java代码中需要编译后文件名StringKt
引用
Kotlin:
fun main() {
val value = mDayOfWeek
}
Java:
public static void main(String[] args) {
String url = StringKt.QQ_URL;
int dayOfWeek = StringKt.getMDayOfWeek();
}
扩展函数表示即使在不修改某个类的源码的情况下,仍然可以向该类添加新的函数。一般都是以顶层函数的方式来定义。
扩展函数的语法结构:
fun ClassName.methodName(param1: Int, param2: Int): Int {
return 0
}
将上面的例子用扩展函数优化下:
fun String.letterCount(): Int {
var count: Int = 0
for (char in this) {
if (char.isLetter()) count++
}
return count
}
将lettersCount()
方法定义成了String
类的扩展函数,那么函数中就自动拥有了String实例的上下文。因此lettersCount()
函数就不再需要接收一个字符串参数了,而是直接遍历this即可。
这样我们就往String
里添加了letterCount
函数。在Java中String是一个final
修饰的类,不可以继承扩展,但是在Kotlin中扩展函数就极大地丰富了String的行为,而且任意Kotlin类均可以进行扩展。