侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

设计不可变Person类并实现伴生对象和模式匹配

2025-12-12 / 0 评论 / 7 阅读

题目

设计不可变Person类并实现伴生对象和模式匹配

信息

  • 类型:问答
  • 难度:⭐⭐

考点

不可变类设计,伴生对象应用,模式匹配实现,apply方法

快速回答

实现要点:

  • 定义主构造器为val的不可变类
  • 伴生对象中实现apply工厂方法
  • 实现unapply方法支持模式匹配
  • 添加isAdult业务方法

代码结构:

class Person private (val name: String, val age: Int) {
  def isAdult: Boolean = age >= 18
}

object Person {
  def apply(name: String, age: Int): Person = new Person(name, age)
  def unapply(p: Person): Option[(String, Int)] = Some((p.name, p.age))
}
## 解析

问题核心

本题要求设计一个符合函数式编程规范的Scala类,重点考察:

  • 不可变数据结构的实现
  • 伴生对象的工厂模式应用
  • 模式匹配的解构能力
  • 业务方法的封装

完整实现代码

// 主构造器参数标记为val确保不可变
class Person private (val name: String, val age: Int) {
  // 业务方法:检查是否成年
  def isAdult: Boolean = age >= 18
}

// 伴生对象
object Person {
  // apply工厂方法(创建实例)
  def apply(name: String, age: Int): Person = new Person(name, age)

  // unapply解构方法(支持模式匹配)
  def unapply(p: Person): Option[(String, Int)] = Some((p.name, p.age))
}

原理说明

  • 不可变性:通过val声明构造参数,确保实例状态不可修改
  • 伴生对象:与类同名且在同一文件,可访问私有构造器
  • apply方法:实现工厂模式,允许Person("Alice", 30)方式创建实例
  • unapply方法:提取器方法,返回Option[Tuple]支持模式匹配

使用示例

// 创建实例
val alice = Person("Alice", 25)

// 模式匹配
val status = alice match {
  case Person(n, a) if a >= 18 => s"$n is adult"
  case Person(n, _) => s"$n is minor"
}

println(status)  // 输出: Alice is adult
println(alice.isAdult)  // 输出: true

最佳实践

  • 构造器私有化:通过private修饰主构造器,强制使用工厂方法
  • 返回Option:unapply应返回Option[Tuple],None表示匹配失败
  • case类替代方案:简单场景可直接用case class(自动生成apply/unapply)

常见错误

  • 忘记将构造参数声明为val,导致无法外部访问
  • unapply返回类型错误(需为Option[TupleN]
  • 未将主构造器私有化,允许new Person(...)直接创建

扩展知识

  • case类原理:case类自动生成apply/unapply/equals/copy等方法
  • 提取器变体:可定义unapplySeq支持变长参数匹配
  • 类型安全:结合密封特质(sealed trait)实现完备的模式匹配检查