Scala——对象(1)

117 阅读2分钟

这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

单例对象

scala中没有静态方法或静态字段,不过可以使用 object 这个语法结构来达到同样的目的。对象定义了某个类的单个实例,包含了我们想要的特性。

object Accounts {
  private var lastNumber = 0
  def newUniqueNumber() = {lastNumber += 1; lastNumber }

  def main(args: Array[String]): Unit = {
    println(Accounts.newUniqueNumber())
    println(Accounts.newUniqueNumber())
    println(Accounts.newUniqueNumber())
    println(Accounts.newUniqueNumber())
    println(Accounts.newUniqueNumber())
  }
}
__________________________________________
输出:
1
2
3
4
5

对象的构造器在第一次使用时被调用,如果一个对象从未被使用,那么其构造器也不会被执行。

对象本质上可以拥有类的所有特性,它甚至可以扩展其他类和特质,只有一个例外,不能提供构造参数

对于任何你在Java中会使用单例对象的地方,在Scala中都可以用对象实现:

  • 作为存放工具函数和常量的地方
  • 高效的共享单个不可变实例
  • 需要用单个实例来协调某个服务时。

伴生对象

在Java中,通常会用到既有实例方法又有静态方法的类,在类中,可以通过类和与类同名的伴生对象来实现。例如:

class Computer {
    var nums: Array[Int] = _;
    def add(): Int = {
      Computer.add(nums)
    }
  }
  
  object Computer {
    def add(nums: Array[Int]): Int = {
      var result = 0;
      nums.iterator.foreach(result += _)
      result
    }
  }
  
  def main(args: Array[String]): Unit = {
    val computer = new Computer
    computer.nums = Array(1, 2, 3, 4, 6, 5, 6, 7)
  }

类和它的伴生对象可以互相访问私有特性,它们必须存在于同一个源文件中。

类的伴生对象可以被访问,但是并不在作用域中。

扩展类或特质的对象

一个对象可以扩展类以及一个或者多个特质,其结果是一个扩展了指定类以及特质的类的对象,同时拥有在对象定义中给出的所有特性。

一个有用的场景是给出可被共享的缺省对象。

apply方法

我们通常会定义和使用对象的方法,当遇到如下形式的表达式时, apply 方法就会被调用:

Object(arg1, ..., argN)

通常这样一个 apply 方法返回的是伴生类的对象。

class Computer {
    private var nums: Array[Int] = _;
    def this(nums: Array[Int]) {
      this()
      this.nums = nums
    }
    def add(): Int = {
      println(Computer.isAdd)  **##可以直接访问Computer对象中的私有对象**
      Computer.add(this.nums)
    }
  }
  object Computer {
    private val isAdd = false;
    def add(nums: Array[Int]): Int = {
      var result = 0;
      nums.iterator.foreach(result += _)
      result
    }
    def apply(nums: Array[Int]): Computer = new Computer(nums)

  }
  def main(args: Array[String]): Unit = {

    val computer = Computer(Array(1, 2, 3, 4, 5, 6, 7))  **##事实上调用了Computer对象中的apply方法**

    println(computer.add())
  }