您的位置:首页 > 其它

Kotlin语法(十五)-对象表达式和声明

2016-11-05 15:03 288 查看
         参考原文:http://kotlinlang.org/docs/reference/object-declarations.html

        

         有时,需要修改一个类的部分功能,可以不通过显式实现一个该类的子类方式来实现。在Java中,通过匿名内部类来实现;在Kotlin中,概括为对象表达式和对象声明(object expressions and object
declarations)。

 

对象表达式(Object expressions)

         创建继承一个或多个类型的匿名类:

window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})


         如果父类型有构造函数,则必须将构造函数的参数赋值;多个父类通过“,”分割:
open class A(x: Int) {
public open val y: Int = x
}

interface B {...}

val ab: A = object : A(1), B {
override val y = 15
}


         有时,只需要一个对象表达式,不想继承任何的父类型,实现如下:
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)


         类似于Java的匿名内部类,对象表达式也可以访问闭合范围内局部变量(跟Java不同,变量不用声明为 final):

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++
}
})
// ...
}

     对象声明(Object declarations)

         单例(Singleton)是一个非常有用的设计模式,在Kotlin中,可以通过下面方式很容易去实现:

object DataProviderManager {
fun registerDataProvider(provider: DataProvider) {
// ...
}
val allDataProviders: Collection<DataProvider>
get() = // ...
}


         这种方式称为对象声明(object declaration),通过在“object ”关键字后面跟上定义的名称即可;它也不再称为一个表达式。不能把它赋值给一个变量,可以通过它的名字来指向它。另外,也可以继承父类:
object DefaultListener : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
}


         注:对象声明(object declaration)不能够定义为局部的(如嵌套在一个函数中),但可以嵌套到其他的对象声明(object declaration)或非内部类中。
 

       友元(伴侣)对象(Companion Objects)

         使用“companion ”关键字修饰,定义在一个类中的对象声明。
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}


         友元(伴侣)对象的成员,可以通过外部类的类名直接访问:
val instance = MyClass.create()

         友元(伴侣)对象的名称,也可以省略,通过“
Companion
”关键字访问该友元(伴侣)对象:

class MyClass {
companion object {
}
}

val x = MyClass.Companion


         友元(伴侣)对象的成员看起来跟其他语言(如Java)的static成员类型;但是在运行时,它是真正的对象的成员实例;还可以实现接口:
interface Factory<T> {
fun create(): T
}

class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
         注:在Java虚拟机(JVM )中,可以将友元(伴侣)对象的成员使用“@JvmStatic”注解,就可以当做一个真正的静态变量或方法。

     对象表达式和对象声明在语义上的区别

         Semanticdifference between object expressions and declarations

         Ø  对象表达式,在它们使用的地方,是立即(immediately)执行(或初始化)。

         Ø  对象声明,会延迟(lazily)初始化;但第一次访问该对象声明时才执行。

         Ø 友元对象(Companion Objects),当外部类被加载通过Java静态初始化方式,会延迟初始化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: