Java是没有这一说法的。Kotlin的对象表达式是用来创建匿名类的对象用的。
interface MyInterface {
fun bar();
}
class Box {
fun foo(f:MyInterface){
f.bar()
}
}
var d = Box()
// 匿名内部类
d.foo(object: MyInterface{
override fun bar() {
print("Ha ha ha")
}
})
如果有一个超类有指定主构造函数,那么就要传递合适的参数,如果有多个超类,则用逗号分隔开(Kotlin也是单继承,但它可以实现多个接口)。
open class A(x:Int) {
public open val y: Int = x
}
interface B {
fun bar();
}
interface C {
fun ba();
}
// 生成一个对象继承A并接实现接口B,C
var abc: A = object: A(21),B,C{
override val y = 15
override fun bar() {
print("B")
}
override fun ba() {
print("C")
}
}
如果我们仅仅是要一个对象,而不需要它有任何的超类,对象表达式,可以让我们快速建出一个对象:
var myA = object {
var x: Int = 10
var y: Int = 100
}
myA.x = 66
print(myA.x * 2 + myA.y)
注意:匿名对象只可以在本地或private
声明中作为类型来使用。如果你使用匿名对象作为public
函数或属性的返回类型,那么这个函数和属性的真实类型应该声明为匿名对象的超类型,如果你没有指定任何超类型,那么就是Any
,且添加在匿名对象的成员将不能访问。
class C {
// Private函数,所以返回类型是匿名对象类型
private fun foo() = object {
val x: String = "x"
}
// Public函数,所以返回类型是Any
fun publicFoo() = object {
val x: String = "x"
}
fun bar() {
val x1 = foo().x //正确
val x2 = publicFoo().x // 报错,它不能访问x
}
}
对象表达式中的代码可以从封闭范围访问变量。:
fun countClicks(window: JComponent) {
var clickCount = 0
var enterCount = 0
window.addMouseListener(object : MouseAdapter() {
// 对象表达式访问封闭它的范围内的变量
override fun mouseClicked(e: MouseEvent) {
clickCount++
}
// 对象表达式访问封闭它的范围内的变量
override fun mouseEntered(e: MouseEvent) {
enterCount++
}
})
// ...
}