Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象,若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明

单例对象语法

基本语法

  1. object Person{
  2. val country:String="China"
  3. }

案例实操
(1)单例对象采用object关键字声明

  1. object Person {
  2. var country: String = "China"
  3. }

(2)单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致

  1. class Person {
  2. var name: String = "bobo"
  3. }

(3)单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问

  1. object Test {
  2. def main(args: Array[String]): Unit = {
  3. println(Person.country)
  4. }
  5. }

apply方法

类名+括号,调用对象的apply方法

  1. 说明

(1)通过伴生对象的apply方法,实现不使用new方法创建对象
(2)如果想让主构造器变成私有的,可以在()之前加上private
(3)apply方法可以重载
(4)Scala 中 obj(arg)的语句实际是在调用该对象的apply方法,即obj.apply(arg);用以统一面向对象编程和函数式编程的风格
(5)当使用new关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实时伴生对象的apply方法

  1. 案例实操 ```scala object Test { def main(args: Array[String]): Unit = { //通过伴生对象的apply方法,实现不使用new关键字创建对象。 val p1 = Person() println(“p1.name=” + p1.name)

    val p2 = Person(“bobo”) println(“p2.name=” + p2.name)

    val p3 = Person.newPerson(“a1”) println(p3.name) } }

//如果想让主构造器变成私有的,可以在()之前加上private class Person private(cName: String) { var name: String = cName }

object Person { //这样实例化也行 def newPerson(cName: String): Person = new Person(cName: String)

def apply(): Person = { println(“apply空参被调用”) new Person(“xx”) }

def apply(name: String): Person = { println(“apply有参被调用”) new Person(name) } //注意:也可以创建其它类型对象,并不一定是伴生类对象

}

  1. <a name="QH2ak"></a>
  2. # 单例模式
  3. <a name="acncf"></a>
  4. ## 饿汉式
  5. 类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快,不使用时就加载到内存,占用了资源
  6. ```scala
  7. // 测试类
  8. object TestSingleextends App {
  9. val boss1 = Boss.getBoss
  10. val boss2 = Boss.getBoss
  11. // 1355531311 1355531311
  12. print(boss1.hashCode() +" " + boss2.hashCode()) // 哈希值相等 对象为同一个 实现了单例
  13. }
  14. /*
  15. 底层代码
  16. public SingleTon getInstance() {
  17. if (s == null) {
  18. s_$eq(new SingleTon());
  19. }
  20. return s();
  21. }
  22. */
  23. // 懒汉式
  24. object Boss {
  25. private var b: Boss= null //先赋值为null
  26. def getBoss= {
  27. if (b== null) {//判断不为null 才实例化对象
  28. b= new Boss //在这里 实例化对象
  29. }
  30. b
  31. }
  32. }
  33. class Boss private() { //Boss类的构造方法私有化
  34. var name: String= _
  35. println("懒汉式~~~")
  36. }

懒汉式

等到引用时才会被加载

//测试类
object TestSingleextends App {
  val b1 = Boss2.getBoss2
  val b2 = Boss2.getBoss2
  // 564160838 564160838  对象为同一个,形成了单例模式
  print(b1.hashCode()  +" " + b2.hashCode())
}

class Boss2 private() { //构造方法私有化
  var age: Int= _
  println("饿汉式~~~")
}

//饿汉式
object Boss2 {
  private val b: Boss2 = new Boss2  //直接实例化对象
  def getBoss2 = {
    b
  }
}