条件类很像普通的类,就只有一点点我们之前说过的关键性的不同。条件类擅长构造不可变数据。下一步,我们将条件类在 模式匹配 中的大用处。
定义条件类(Defining a case class)
一个最小条件类需要关键字 case class
,一个类名和一个参数列表(可能为空):
case class Book(isbn: String)
val frankenstein = Book("978-0486282114")
注意:在实例化 Book
条件类时没有使用 new
关键字。这是因为条件类默认有一个叫做 apply
的方法完成了构造器的功能。
当我们创建一个有参数的条件类时,参数默认是公有的 val
常量。
case class Message(sender: String, recipient: String, body: String)
val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "Ça va ?")
println(message1.sender) // prints guillaume@quebec.ca
message1.sender = "travis@washington.us" // this line does not compile
你不能对 message1.sender
重复赋值,因为它是一个常量(不可变的值)。在条件类中是可以使用 var
变量的,不过不鼓励。
比较(Comparison)
条件类比较不是通过比较是否指向同一个地址,而是通过比较类中的结构是否相同来确定两个条件类是否相等。
case class Message(sender: String, recipient: String, body: String)
val message2 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?")
val message3 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?")
val messagesAreTheSame = message2 == message3 // true
尽管 message2
和 message3
指向不同的对象,但是两个对象的值是相同的,那么,它们就是相同的。
复制(Copying)
你可以非常简单的通过条件类的 copy
方法来复制出另一个条件类的实例。甚至你可以改变另一个实例的部分参数。
case class Message(sender: String, recipient: String, body: String)
val message4 = Message("julien@bretagne.fr", "travis@washington.us", "Me zo o komz gant ma amezeg")
val message5 = message4.copy(sender = message4.recipient, recipient = "claire@bourgogne.fr")
message5.sender // travis@washington.us
message5.recipient // claire@bourgogne.fr
message5.body // "Me zo o komz gant ma amezeg"
message4
中的 recipient 成员的值变成了 message5
中的 sender 成员中的值。而 message4
中 body 成员的值被直接复制到了 message5
中。