单例对象
对象是只有一个实例的类。当它被引用时,它会被怠慢创建,就像lazy val一样。
作为顶层值,对象是单例。
作为一个封闭类的成员或本地值,它的行为与lazy val完全相同。
1 定义单例对象
一个对象是一个值。对象的定义类似class,但是使用关键字object。
# 定义对象
object Box
# 定义对象(具有方法)
object Logger {
def info(message: String): Unit = println(s"INFO: $message")
}
2 引用对象
import logging.Logger.info
class Project(name: String, dayToComplete: Int)
class Test{
val project1 = new Project("TPS Reports", 1)
val project2 = new Project("Website redesign", 5)
info("Created projects")
}
note:通过import语句,info方法可见。
ps:引入需要被引入符号的可靠路径,对象为可以作为可靠路径。
ps:如果一个对象并非位于顶层,而是嵌套于其他的类或对象中,那么,这个对象将和其他成员一样,是“路径依赖”的。
3 伴侣对象
与类同名的对象称之为伴侣对象。与之对应,类为对象的伴侣类。伴侣对象或伴侣类可以访问其伴侣的私有成员。对于伴侣类的实例而言,用于伴侣对象的方法与值并非是特定的。
import scala.math._
# 定义伴侣类
case class Circle(radius: Double) {
import Circle.calculateArea
def area: Double = calculateArea(radius)
}
# 定义伴侣对象
object Circle {
private def calculateArea(radius: Double):Double = Pi * pow(radius, 2.0)
}
note:Circle类成员area非单例,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
}
}
如果类或对象具有伴侣,它们就必须位于同一个文件中。
4 注意
Java中的静态成员在Scala中被建模为伴侣对象的普通成员。
当使用Java代码中的伴随对象时,定义在伴随类中的成员需要带有static修饰语。这被称为静态转发。即使没有在伴随类中定义,也会出现。