今天学习一下Kotlin中的对象表达式。
对象表达式,是一种代替Java中的匿名内部类的方法。下面看看具体的用法,以及它与Java匿名内部类之间的区别。
代替Java匿名内部类
我们都知道Java的匿名内部类,这里给一个最简单的匿名内部类的Java代码示例:
String[] fileList = new File("./").list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return false;
}
});
那上面的匿名内部类在Kotlin中应该怎么写呢,就是使用object关键字来进行编写,基本结构与Java匿名内部类还是非常相似的,代码示例如下:
val fileList = File("./").list(
object: FilenameFilter {
//重写其中的方法
override fun accept(dir: File?, name: String?): Boolean {
return false
}
}
);
你会发现上面的用法跟匿名内部类非常像,当然其实上面的代码还是可以被优化的,只是这里特意写成这样来说明问题。
实现多个接口
在Java中匿名内部类智能只能继承一个类或者实现一个接口,而Kotlin的匿名对象可以实现多个接口或者不实现接口。
//匿名内部类实现了FilenameFilter接口
String[] fileList = new File("./").list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return false;
}
});
可以看出上面的Java代码匿名内部类实现了FilenameFilter这个接口,并且只能实现一个。但是Kotlin却没有这个限制。代码示例如下:
interface A{
fun aTest()
}
interface B{
fun bTest()
}
//对象表达式实现多个接口
val myObj: Any = object : A, B{
override fun bTest() {
}
override fun aTest() {
}
}
同时上面的示例也可以看出,当我们的一个对象表达式的实例需要反复使用时,我们可以给该实例分配一个名字。
访问局部变量
我们知道在Java中,被匿名内部类访问的变量必须被final修饰符修饰。代码示例如下:
private void Example(Window window){
int i = 0;
window.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
//错误,i必须声明为final的
i++;
}
});
}
而在Kotlin中没有这种限制,对象表达式可以直接访问创建它的函数内部的变量,并且修改其值。同样是上面的例子我们看看Kotlin中的代码例子:
private fun Example(window: Window) {
var i = 0
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent?) {
super.mouseClicked(e)
//i的值可以被正常修改
i++
}
})
}
看出上面Kotlin中i的值可以被正常修改不会报错。
写在最后
今天的对象表达式的知识点其实是object关键字的用法之一,它的出现可以很好地帮我们解决一些Kotlin编程中的特殊场景的问题。