Scala 中 case class 与 class 的对比及代码解析

34 阅读3分钟

在 Scala 编程中,case class(样例类)和普通class是定义类的两种常用方式,二者在语法特性、使用场景上有明显区别。本文通过代码示例拆解它们的核心差异。

以下是示例代码(包含case class与普通class的定义及使用):

scala

package caseclass

/*
case class (样例类) v.s. class(类)
1. case class 可以在实例化对象时,省略new
2. case class 的属性在默认情况下是只读的。如果希望可以修改,就需要主动使用var。
3. case class 会自动重写 equals, toString ......
当我们只需要使用类来表示数据的时候,就可以选择使用case class,它更加简单!
*/
object caseclass92 {
  case class Student1(val id:String, var name:String) {
  }

  class Student2(var id:String, var name:String) {
  }

  def main(args: Array[String]): Unit = {
    val stu1 = new Student2("1", "小花")
    val stu2 = new Student2("1", "小花")
    println(stu1 == stu2)

    println(stu1)
    println(Student1("1", "小花"))
    // stu1.name = "小花花"
    // val stu2 = new Student2("1", "小花")
  }
}

二、代码含义解析

1. 包与对象定义

代码开头通过package caseclass声明所属包,后续将Student1(case class)、Student2(普通 class)定义在单例对象caseclass92中,这是 Scala 中组织代码的常用方式。

2. case class 的定义:Student1

scala

case class Student1(val id:String, var name:String)

这是一个case class,核心特性对应注释中的说明:

  • 省略new实例化:创建Student1对象时,无需写new,直接通过Student1("1", "小花")即可(如main方法中println(Student1("1", "小花")))。
  • 属性的可变性idval修饰(默认也是val),是只读属性namevar修饰,是可修改属性
  • 自动重写方法case class会自动生成equals(用于对象内容比较)、toString(用于打印对象详情)等方法。

3. 普通 class 的定义:Student2

scala

class Student2(var id:String, var name:String)

这是一个普通class,与case class的差异在于:

  • 必须用new实例化:创建Student2对象时,必须写new(如val stu1 = new Student2("1", "小花"))。
  • 无默认方法重写:普通class不会自动重写equalstoString,默认equals是 “引用比较”(比较对象地址),toString打印的是对象的内存地址。

4. main 方法中的逻辑

  • 普通 class 的==比较

    scala

    val stu1 = new Student2("1", "小花")
    val stu2 = new Student2("1", "小花")
    println(stu1 == stu2)
    

    由于普通classequals是引用比较,stu1stu2是两个不同对象,因此stu1 == stu2会输出false

  • 普通 class 的toString

    scala

    println(stu1)
    

    普通classtoString默认输出格式类似caseclass.caseclass92$Student2@xxxxxx(内存地址)。

  • case class 的实例化与打印

    scala

    println(Student1("1", "小花"))
    

    case classtoString会自动打印属性内容,输出格式为Student1(1,小花)

三、case class 与普通 class 的核心差异总结

特性case class普通 class
实例化方式可省略new(如Student1(...)必须用new(如new Student2(...)
属性默认修饰符val(只读)无默认,需显式写val/var
自动重写的方法equals(内容比较)、toString无,默认是引用比较、打印内存地址
适用场景数据载体(仅存数据,无复杂逻辑)包含复杂业务逻辑的类