构造函数 #

一、主构造函数 #

1.1 基本语法 #

主构造函数的参数直接放在类名后面:

scala
class Person(name: String, age: Int):
  def greet(): String = s"Hello, I'm $name, $age years old"

val person = Person("Alice", 25)
println(person.greet())

1.2 参数可见性 #

scala
class Person(
  val name: String,
  var age: Int,
  private val id: String
):
  def info: String = s"$name (ID: $id)"

val person = Person("Alice", 25, "P001")
println(person.name)
person.age = 26

1.3 参数修饰符 #

修饰符 说明
无修饰符 仅构造函数内可见
val 只读属性
var 可变属性
private val/var 私有属性

1.4 默认参数值 #

scala
class Person(
  val name: String = "Unknown",
  val age: Int = 0
)

val p1 = Person()
val p2 = Person("Alice")
val p3 = Person("Bob", 25)
val p4 = Person(age = 30)

二、构造函数体 #

2.1 类体作为构造函数体 #

类体中的代码在构造时执行:

scala
class Person(name: String, age: Int):
  println(s"Creating person: $name")
  
  val birthYear: Int = java.time.Year.now.getValue - age
  
  def greet(): String = s"Hello, I'm $name, born in $birthYear"

val person = Person("Alice", 25)
println(person.birthYear)

2.2 初始化块 #

scala
class DatabaseConnection(url: String):
  println(s"Connecting to $url...")
  
  private val connection = connect()
  
  private def connect(): Connection =
    println("Connection established")
    ???
  
  def query(sql: String): Result = ???
  
  def close(): Unit =
    println("Closing connection...")
    ???

2.3 延迟初始化 #

scala
class HeavyResource(path: String):
  lazy val data: String =
    println("Loading data...")
    scala.io.Source.fromFile(path).mkString
  
  def process(): String =
    s"Processing: ${data.take(100)}"

val resource = HeavyResource("data.txt")
println("Created")
resource.process()

三、辅助构造函数 #

3.1 定义辅助构造函数 #

使用 def this(...) 定义:

scala
class Person(val name: String, val age: Int):
  def this(name: String) = this(name, 0)
  def this() = this("Unknown")

val p1 = Person("Alice", 25)
val p2 = Person("Bob")
val p3 = Person()

3.2 辅助构造函数规则 #

  • 第一个语句必须调用其他构造函数
  • 最终必须调用主构造函数
scala
class Rectangle(val width: Double, val height: Double):
  def this(size: Double) = this(size, size)
  def this() = this(1.0)
  
  def area: Double = width * height
  def isSquare: Boolean = width == height

val r1 = Rectangle(10, 20)
val r2 = Rectangle(5)
val r3 = Rectangle()

3.3 复杂辅助构造函数 #

scala
class Date(val year: Int, val month: Int, val day: Int):
  def this(year: Int, dayOfYear: Int) =
    this(year, 1, 1)
  
  def this(timestamp: Long) =
    this(1970, 1, 1)

val d1 = Date(2024, 3, 27)
val d2 = Date(2024, 86)
val d3 = Date(System.currentTimeMillis())

四、私有构造函数 #

4.1 私有主构造函数 #

scala
class Singleton private ():
  def doSomething(): String = "Working..."

object Singleton:
  private val instance = Singleton()
  def getInstance: Singleton = instance

val singleton = Singleton.getInstance

4.2 工厂方法模式 #

scala
class Person private (val name: String, val age: Int)

object Person:
  def apply(name: String, age: Int): Person = new Person(name, age)
  def child(name: String): Person = new Person(name, 0)
  def adult(name: String): Person = new Person(name, 18)
  def unknown: Person = new Person("Unknown", 0)

val p1 = Person("Alice", 25)
val p2 = Person.child("Bob")
val p3 = Person.adult("Charlie")
val p4 = Person.unknown

4.3 私有辅助构造函数 #

scala
class Config private (val settings: Map[String, String]):
  private def this() = this(Map.empty)

object Config:
  def fromFile(path: String): Config =
    val settings = scala.io.Source.fromFile(path)
      .getLines()
      .map(_.split("=", 2))
      .map(arr => arr(0) -> arr(1))
      .toMap
    Config(settings)
  
  def default: Config = Config(Map("timeout" -> "5000"))

val config = Config.fromFile("config.properties")
val defaultConfig = Config.default

五、构造函数参数详解 #

5.1 无修饰符参数 #

仅构造函数内可见:

scala
class Person(name: String, age: Int):
  def greet(): String = s"$name, $age"
  
val person = Person("Alice", 25)

5.2 val 参数 #

创建只读属性:

scala
class Person(val name: String, val age: Int)

val person = Person("Alice", 25)
println(person.name)

5.3 var 参数 #

创建可变属性:

scala
class Person(var name: String, var age: Int)

val person = Person("Alice", 25)
person.name = "Bob"
person.age = 26

5.4 private 参数 #

私有属性:

scala
class Person(private val name: String, private val age: Int):
  def info: String = s"$name, $age"

val person = Person("Alice", 25)
println(person.info)

5.5 protected 参数 #

受保护属性:

scala
class Animal(protected val name: String)

class Dog(name: String) extends Animal(name):
  def bark(): String = s"$name says: Woof!"

val dog = Dog("Rex")
println(dog.bark())

六、构造函数与继承 #

6.1 调用父类构造函数 #

scala
class Animal(val name: String):
  def speak(): String = "Some sound"

class Dog(name: String, val breed: String) extends Animal(name):
  override def speak(): String = s"$name says: Woof!"

val dog = Dog("Rex", "German Shepherd")
println(dog.speak())
println(dog.breed)

6.2 构造函数参数传递 #

scala
class Vehicle(val brand: String, val year: Int)

class Car(brand: String, year: Int, val model: String) 
  extends Vehicle(brand, year):
  def info: String = s"$brand $model ($year)"

val car = Car("Toyota", 2024, "Camry")
println(car.info)

6.3 多层继承 #

scala
class A(val x: Int)
class B(x: Int, val y: Int) extends A(x)
class C(x: Int, y: Int, val z: Int) extends B(x, y):
  def sum: Int = x + y + z

val c = C(1, 2, 3)
println(c.sum)

七、构造函数最佳实践 #

7.1 使用主构造函数 #

scala
class Person(val name: String, val age: Int)

class Person(name: String, age: Int):
  val _name = name
  val _age = age

7.2 使用默认参数代替辅助构造函数 #

scala
class Person(val name: String = "Unknown", val age: Int = 0)

class Person(val name: String, val age: Int):
  def this(name: String) = this(name, 0)
  def this() = this("Unknown")

7.3 使用工厂方法 #

scala
class Connection private (val host: String, val port: Int)

object Connection:
  def apply(host: String, port: Int): Connection = 
    new Connection(host, port)
  
  def localhost(port: Int = 8080): Connection = 
    new Connection("localhost", port)
  
  def fromUrl(url: String): Connection =
    val uri = java.net.URI(url)
    new Connection(uri.getHost, uri.getPort)

val c1 = Connection("example.com", 80)
val c2 = Connection.localhost()
val c3 = Connection.fromUrl("http://api.example.com:8080")

7.4 验证构造参数 #

scala
class Person(val name: String, val age: Int):
  require(name.nonEmpty, "Name cannot be empty")
  require(age >= 0 && age <= 150, "Age must be between 0 and 150")

Person("Alice", 25)
Person("", 25)
Person("Bob", 200)

八、总结 #

构造函数类型 #

类型 语法 说明
主构造函数 class Name(params) 类定义时指定
辅助构造函数 def this(params) 必须调用其他构造函数
私有构造函数 class Name private 禁止外部实例化

参数修饰符 #

修饰符 可见性 可变性
仅构造函数内 -
val 公开 只读
var 公开 可变
private val/var 私有 取决于 val/var

下一步,让我们学习 继承与多态

最后更新:2026-03-27