在 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", "小花")))。 - 属性的可变性:
id用val修饰(默认也是val),是只读属性;name用var修饰,是可修改属性。 - 自动重写方法:
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不会自动重写equals、toString,默认equals是 “引用比较”(比较对象地址),toString打印的是对象的内存地址。
4. main 方法中的逻辑
-
普通 class 的
==比较:scala
val stu1 = new Student2("1", "小花") val stu2 = new Student2("1", "小花") println(stu1 == stu2)由于普通
class的equals是引用比较,stu1和stu2是两个不同对象,因此stu1 == stu2会输出false。 -
普通 class 的
toString:scala
println(stu1)普通
class的toString默认输出格式类似caseclass.caseclass92$Student2@xxxxxx(内存地址)。 -
case class 的实例化与打印:
scala
println(Student1("1", "小花"))case class的toString会自动打印属性内容,输出格式为Student1(1,小花)。
三、case class 与普通 class 的核心差异总结
| 特性 | case class | 普通 class |
|---|---|---|
| 实例化方式 | 可省略new(如Student1(...)) | 必须用new(如new Student2(...)) |
| 属性默认修饰符 | val(只读) | 无默认,需显式写val/var |
| 自动重写的方法 | equals(内容比较)、toString等 | 无,默认是引用比较、打印内存地址 |
| 适用场景 | 数据载体(仅存数据,无复杂逻辑) | 包含复杂业务逻辑的类 |