建構函式

主建構函式

在 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 has no other members or methods, so the body may be omitted

val foo = new Foo(4, "ab")
val baz = new Baz("I am a baz")
foo.x // will not compile: x is not a member of 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() // Constructor parentheses are optional here

例項化物件例項時應執行的任何操作都直接寫在類的主體中:

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
    ...
}

請注意,將儘可能少的副作用放入建構函式中被認為是一種好習慣; 應該考慮使用 connectdisconnect 方法而不是上面的程式碼,以便消費者程式碼負責排程 IO。

輔助構造器

類可能有其他建構函式稱為輔助建構函式。這些是由 def this(…) = e 形式的建構函式定義定義的,其中 e 必須呼叫另一個建構函式:

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

// usage:
new Person("Grace Hopper").fullName // returns Grace Hopper
new Person("Grace", "Hopper").fullName // returns Grace Hopper

這意味著每個建構函式都可以有一個不同的修飾符:只有一些可以公開使用:

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

new Person("Ada Lovelace") // won't compile
new Person("Ada", "Lovelace") // compiles

通過這種方式,你可以控制使用者程式碼如何例項化該類。