构造函数
主构造函数
在 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
通过这种方式,你可以控制使用者代码如何实例化该类。