建構函式
主建構函式
在 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
...
}
請注意,將儘可能少的副作用放入建構函式中被認為是一種好習慣; 應該考慮使用 connect
和 disconnect
方法而不是上面的程式碼,以便消費者程式碼負責排程 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
通過這種方式,你可以控制使用者程式碼如何例項化該類。