Scala构造函数

例子

主构造器

在 Scala 中,主要构造函数是类的主体。类名后跟一个参数列表,它们是构造函数的参数。(与任何函数一样,可以省略空参数列表。)

class Foo(x: Int, y: String) {
    val xy: String = y * x
    /* now xy is a public member of the class */
}

class Bar {
    ...
}

除非通过val关键字标记为实例成员,否则在其构造函数主体之外无法访问实例的构造参数:

class Baz(val z: String) 
// Baz 没有其他成员或方法,因此可以省略主体

val foo = new Foo(4, "ab")
val baz = new Baz("I am a baz")
foo.x // 不会编译:x 不是 Foo 的成员
foo.xy // returns "abababab": xy is a member of Foo
baz.z // returns "I am a baz": z is a member of Baz
val bar0 = new Bar
val bar1 = new Bar() // 构造函数括号在这里是可选的

实例化对象的实例时应该执行的任何操作都直接写入类的主体中:

class DatabaseConnection
    (host: String, port: Int, username: String, password: String) {
    /* first connect to the DB, or throw an exception */
    private val driver = new AwesomeDB.Driver()
    driver.connect(host, port, username, password)
    def isConnected: Boolean = driver.isConnected
    ...
}

请注意,将尽可能少的副作用放入构造函数被认为是一种很好的做法;而不是上面的代码,应该考虑拥有connect和disconnect方法,以便消费者代码负责调度 IO。

辅助构造函数

一个类可能有额外的构造函数,称为“辅助构造函数”。这些由构造函数定义以 形式定义def this(...) = e,其中e必须调用另一个构造函数:

class Person(val fullName: String) {    
  def this(firstName: String, lastName: String) = this(s"$firstName $lastName")
}

// 用法:
new Person("Grace Hopper").fullName // 格蕾丝·霍珀归来
new Person("Grace", "Hopper").fullName // 格蕾丝·霍珀归来

这意味着每个构造函数可以有不同的修饰符:只有一些可能是公开的:

class Person private(val fullName: String) {    
  def this(firstName: String, lastName: String) = this(s"$firstName $lastName")
}

new Person("Ada Lovelace") // 不会编译
new Person("Ada", "Lovelace") // 编译

通过这种方式,您可以控制使用者代码如何实例化类。