对象表达式
如果我们只需要“一个对象而已”,并不需要特殊超类型,那么我们可以简单地写:
fun foo() {
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
匿名对象只能在本地和私有作用域中声明类型 比如下面的就访问不到
var adHoc = object {
var x: Int = 0
var y: Int = 0
}
fun foo() {
// 这里的adHoc.x 访问不到
// print(adHoc.x)
}
使用匿名对象作为公有函数的返回类型或者用作公有属性的类型,那么该函数或属性的实际类型会是匿名对象声明的超类型,如果你没有声明任何超类型,就会是 Any。在匿名对象中添加的成员将无法访问。
class C {
private fun foo() = object {
val x: String = "x"
}
fun publicFoo() = object {
val x: String = "x"
}
fun bar() {
val x1 = foo().x // 没问题
val x2 = publicFoo().x //
}
}
伴生对象
伴生对象使用companion 关键字标记
class MyTest {
companion object Factory {
fun create(): MyTest = MyTest()
}
}
该伴生对象的成员可通过只使用类名作为限定符来调用:
val instance = MyClass.create()
可以省略伴生对象的名称,在这种情况下将使用名称 Companion:
class MyClass {
companion object { }
}
val x = MyClass.Companion
即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员,在 JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象的成员生成为真正的静态方法和字段