提出问题:有一群小朋友在玩堆雪人,不时有新的小朋友加入,请问如何计算现在有几个小朋友?【使用面向对象的思想
初步分析:

  • 在 Java 中,可以使用静态属性解决该问题,即通过类对象调用,这种操作不是面向对象的
  • 然而 Scala 是完全面向对象的,所以并没有静态相关的操作,这就需要提出解决办法

进一步分析:为了和 Java 无缝衔接,Scala 就使用了一种特殊的对象来模拟类,我们称之为伴生对象

案例研究

  1. object AccompanyObject {
  2. def main(args: Array[String]): Unit = {
  3. val c1 = new Child("zhangsan")
  4. c1.showInfo
  5. Child.showInfo(c1)
  6. // c1.age 无法访问
  7. val c2 = new Child("lisi")
  8. Child.joinGame(c1)
  9. Child.joinGame(c2)
  10. println("total: " + Child.total)
  11. }
  12. }
  13. // 伴生对象
  14. object Child {
  15. var total = 0
  16. def showInfo(c: Child): Unit = {
  17. println(s"object Child: name=${c.name}, age=${c.age}")
  18. }
  19. def joinGame(c: Child): Unit = {
  20. println(s"${c.name} 加入游戏!")
  21. total += 1
  22. }
  23. }
  24. // 伴生类
  25. class Child(inName: String) {
  26. var name: String = inName
  27. private var age: Int = _
  28. def showInfo: Unit = {
  29. println(s"class Child: name=$name, age=$age")
  30. }
  31. }

语法介绍

定义:在同一个文件中,以“object”关键字声明的称为伴生对象,和它同名的“class xxx”称为伴生类
区别:

  • 伴生对象中是静态内容,伴生类中是非静态内容(存放内容性质不同)
  • 伴生对象中的属性和方法通过类名访问,伴生类中的通过该类实例访问(访问方式不同)

📝 注意点

  • 伴生对象和伴生类的声明必须在同一个源文件中,否则运行发生错误
  • 如果伴生对象单独存在,那么它就是一个“静态”性质的对象,即类对象
  • 如果伴生类单独存在,那么它就是一个普通的类

✍ 底层原理是如何实现的?

  • “object Child”对应 Child$.classChild$.java
  • “class Child”对应 Child.classChild.java
  • 访问机制AccompanyObject$.java

    apply方法

    在伴生对象中可以定义 apply 方法,可以实现“类名(参数)”的方式创建对象,具体参考一下的案例 ```scala // 自行测试 object Test { def main(args: Array[String]): Unit = { // 使用 apply 方式创建对象 val p = Pig(“小黑”) // 自动触发apply(name: String) println(p) // 实际使用的是 toString 方法 } }

object Pig { def apply(name: String): Pig = new Pig(name) def apply(): Pig = new Pig(“小花”) }

class Pig(pName: String) { var name: String = pName // 重写 toString 方法 override def toString: String = this.name } ```