构造函数 #
一、主构造函数 #
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