13.scala的单例对象

Posted 大数据群英萃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13.scala的单例对象相关的知识,希望对你有一定的参考价值。

单例对象是一种特殊的类,有且只有一个实例。和惰性变量一样,单例对象是延迟创建的,当它第一次被使用时创建。

当对象定义于顶层时(即没有包含在其他类中),单例对象只有一个实例。

当对象定义在一个类或方法中时,单例对象表现得和惰性变量一样。

一个单例对象是就是一个值。单例对象的定义方式很像类,但是使用关键字 object

object Box

下面例子中的单例对象包含一个方法:

package logging
object Logger { def info(message: String): Unit = println(s"INFO: $message")}

方法 info 可以在程序中的任何地方被引用。像这样创建功能性方法是单例对象的一种常见用法。


下面让我们来看看如何在另外一个包中使用 info 方法:

import logging.Logger.info
class Project(name: String, daysToComplete: Int)
class Test { val project1 = new Project("TPS Reports", 1) val project2 = new Project("Website redesign", 5) info("Created projects") }

因为 import 语句 import logging.Logger.info,方法 info 在此处是可见的。

import语句要求被导入的标识具有一个“稳定路径”,一个单例对象由于全局唯一,所以具有稳定路径。

注意:如果一个 object 没定义在顶层而是定义在另一个类或者单例对象中,那么这个单例对象和其他类普通成员一样是“路径相关的”。这意味着有两种行为,class Milkclass OrangeJuice,一个类成员 object NutritionInfo “依赖”于包装它的实例,要么是牛奶要么是橙汁。milk.NutritionInfo 则完全不同于oj.NutritionInfo

伴生对象

当一个单例对象和某个类共享一个名称时,这个单例对象称为 伴生对象。同理,这个类被称为是这个单例对象的伴生类。类和它的伴生对象可以互相访问其私有成员。使用伴生对象来定义那些在伴生类中不依赖于实例化对象而存在的成员变量或者方法。

import scala.math._
case class Circle(radius: Double) { import Circle._ def area: Double = calculateArea(radius)}
object Circle { private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)}
val circle1 = Circle(5.0)
circle1.area

这里的 class Circle 有一个成员 area 是和具体的实例化对象相关的,单例对象 object Circle 包含一个方法 calculateArea ,它在每一个实例化对象中都是可见的。

伴生对象也可以包含工厂方法:

 
class Email(val username: String, val domainName: String)
object Email { def fromString(emailString: String): Option[Email] = { emailString.split('@') match { case Array(a, b) => Some(new Email(a, b)) case _ => None } }}
val scalaCenterEmail = Email.fromString("scala.center@epfl.ch")scalaCenterEmail match { case Some(email) => println( s"""Registered an email |Username: ${email.username} |Domain name: ${email.domainName} """) case None => println("Error: could not parse email")}

注意:类和它的伴生对象必须定义在同一个源文件里。如果需要在 REPL 里定义类和其伴生对象,需要将它们定义在同一行或者进入 :paste 模式。


Java 程序员的注意事项


在 Java 中 static 成员对应于 Scala 中的伴生对象的普通成员。

在 Java 代码中调用伴生对象时,伴生对象的成员会被定义成伴生类中的 static 成员。这称为 静态转发。这种行为发生在当你自己没有定义一个伴生类时。

推荐阅读:



以上是关于13.scala的单例对象的主要内容,如果未能解决你的问题,请参考以下文章

性能比较好的单例写法

python中的单例设计模式

如何写一个简单的单例模式?

Java中的单例模式

Kotlin 中带参数的单例

比想象中复杂一点的单例模式