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

         参考原文: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静态初始化方式,会延迟初始化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值