关于scala:Scala-伴生对象

53次阅读

共计 2020 个字符,预计需要花费 6 分钟才能阅读完成。

伴生对象和伴生类

在后面的文章中,可能也有人留神到 main 办法并没有像 java 的 static 关键字,而且运行 main 办法的类定义的是 object。object 定义的类和 class 定义的类名字还能够一样。
比方 class ScalaObject 和 object ScalaObject,咱们能够说 object ScalaObject 是 class ScalaObject 的伴生对象,class ScalaObject 是 object ScalaObject 的伴生类。伴生对象和伴生类能够互相拜访公有的属性和办法。
在 scala 中定义伴生对象的属性和办法:

object ScalaObject2 {
  var str: String = "str"

  def fun(): Unit = {println("fun")
  }
}

编译后会看到有 ScalaObject2 和 ScalaObject2$ 两个 class 文件。
ScalaObject2 反编译如下,这里有 3 个静态方法,一个是咱们下面定义的 fun,另外一个就是 str 的 set 和 get 办法。ScalaObject2.str 就是调用 get 办法,ScalaObject2.str=”str2″ 就是调用 set 办法。
在 static 里能间接调用 ScalaObject2..MODULE$,所以咱们晓得 ScalaObject2..MODULE$ 也是动态的。

ScalaObject2$ 反编译如下,从这里能够看出,他实际上是一个单例对象。构造函数用 private 润饰,而后又用 this 指向 MODULE$,让 MODULE$ 对外提供办法。

在上面的例子中,str 是伴生类 ScalaObject 的公有属性,在伴生对象 ScalaObject 中,是能够间接拜访的,所以伴生对象和伴生类能够互相拜访公有的属性和办法。

class ScalaObject {private var str: String = "str"}

object ScalaObject {def main(args: Array[String]): Unit = {val scalaObject = new ScalaObject()
    println(scalaObject.str)
  }
}

单例

相似 java 的单例模式:
首先结构器默认 private 的,此时是不能间接通过结构器来创立这个对象,而后在伴生对象中,申明一个办法用于创立这个对象,因为伴生对象和伴生类能够相互调用公有办法,所以是能够通过结构器来创立这个对象。

object ScalaObject3 {
  private val scalaObject3: ScalaObject3 = new ScalaObject3

  def getInstance(): ScalaObject3 = {scalaObject3}
}

class ScalaObject3 private() {}

而后在 Test 中创立一个单例,间接通过 new 是不行的,所以通过伴生对象来获取。运行后,能够看到两个地址是一样的。

object Test {def main(args: Array[String]): Unit = {//new ScalaObject3()//erro
    val scalaObject1 = ScalaObject3.getInstance()
    val scalaObject2 = ScalaObject3.getInstance()
    println(scalaObject1)
    println(scalaObject2)
  }
}

apply

咱们在伴生对象中定义 apply 办法,而后间接类目 + 参数(有可能无参),实际上调用的是伴生对象的 apply 办法。
比方在上面例子中,间接调用 ScalaObject4(“hello”) 实际上调用的是 ScalaObject4.apply 办法,所以 apply 是能够省略的。

object Test4 {def main(args: Array[String]): Unit = {ScalaObject4("hello")
    ScalaObject4.apply("hello")
  }
}

object ScalaObject4 {def apply(str: String): Unit = {println(str)
  }
}

另外一个就是能够省略到 new 关键字。上面例子中,ScalaObject5 的结构器是公有的,所以间接 new 一个对象是不行的,ScalaObject5 是调用 apply 办法才返回的 ScalaObject5 实例。
比方 List(1,2,3),其实就是调用 apply 办法。

object Test5 {def main(args: Array[String]): Unit = {
    val scalaObject = ScalaObject5
    //val scalaObject1 = new ScalaObject5 erro
  }
}

object ScalaObject5 {def apply(): ScalaObject5 = {new ScalaObject5}
}
class ScalaObject5 private{}

正文完
 0