Kotlin开发之——对象表达式和对象声明

概述

在java中,不管是为了实现接口或者抽象类类,我们总是习惯使用匿名内部类。最熟悉的例子,莫过于对单击事件的监听,也就是这样写:

btn.setOnClickListener(new OnClickListener{//处理单击事件逻辑});

尽管该匿名类只能被使用一次,这样,我们没有必要再去实现OnClickListener接口并创建一个类,从而简化了代码。可是,在kotlin中,并没有匿名类这一概念。巧妇无米之炊啊,碰到监听事件或者回调,是不是得老老实实的写一个实现类呢?尽管Kotlin没有匿名内部类,恰巧其用object一个简单的关键字,解决了这一个问题。下面我们来看看神奇的object有什么魔法效果呢?

对象表达式

在kotlin中,object的神奇之对象表达式,什么是对象表达式呢?我们把它认为是一个匿名内部类的实例,该匿名类可以继承自某个类或者多个接口。不过,我们需要通过object关键字将其声明,表示这是一个对象。对于文章开始的单击事件监听我们可以这么写:

btn.setOnClickListener(object : OnClickListener{// 处理单击事件逻辑});

注:

  • 如果被继承的基类中为有参构造器且没有无参构造器时,那么必须向构造器传递适当的参数,否则编译器会报错。

  • 对象表达式内的代码可以访问创建这个对象的代码范围内的变量,与Java不同的是,被访问的变量不需要被限制为final变量

      val a = 10
      val listener = object : Info("submit"),IClickListener 
      {
          override fun doClick() 
          {
              println("a:$a")
          }
      }
      listener.doClick() // 打印 a:10
    
  • 只需要对象,而不需要继承任何有价值的基类,可以简单些:

      val adHoc = object
      {
          var x: Int = 0
          var y: Int = 0
      }
      print(adHoc.x + adHoc.y)
    

对象声明

当关键字object之后指定了一个名称,那么它就不再是对象表达式,而是一个对象声明。此时对象不再是表达式,看作类的变种更为合适吧,不能再将其赋值给一个变量。在使用它时,只需要它的名字引用既可。

object MyInfo: Info("submit"),IClickListener
{
    override fun doClick() 
    {
        println("MyInfo do click, $text") // Log: MyInfo do click, , submit
    }
}
fun main(args: Array<String>) 
{
    MyInfo.doClick()
}

注:

  • 对象声明不可以是局部的(也就是说,不可以直接嵌套在函数之内),但可以嵌套在另一个对象声明之内,或者嵌套在另一个非内部类(non-inner class)内
  • 被声明的对象可以被指定基类(类,接口)
  • 对象声明不能指定构造函数
  • 与对象表达式相似,如果被继承的基类中为有参构造器且没有午餐构造器时,那么必须向构造器传递适当的参数,否则编译器会报错。

参考:
Kotlin-对象表达式,对象声明及伴随对象