普通类只有在伴生对象中定义apply和unapply方法才能够利用伴生对象的方式创建对象和模式匹配
/**
- apply方法通常称为注入方法,在伴生对象中做一些初始化操作
- apply方法的参数列表不需要和构造器的参数列表统一
- unapply方法通常称为提取方法,使用unapply方法提取固定数量的参数来进行模式匹配
- unapply方法会返回一个序列(Option),内部产生一个Some对象,Some对象存放一些值
- apply方法和unapply方法会被隐式的调用
- @param name
- @param age
- @param faceValue
*/
class ApplyDemo(val name: String, var age: Int, var faceValue: Int) {
}
object ApplyDemo {
//注入方法
def apply( name:String, age:Int,gender:Int,faceValue:Int): ApplyDemo =
new ApplyDemo(name,age,faceValue)
//提取方法:提取固定数量的参数
def unapply(applyDemo: ApplyDemo): Option[(String, Int, Int)] ={
if(applyDemo ==null){
None
}else{
Some(applyDemo.name,applyDemo.age,applyDemo.faceValue)
}
}
}
object test3{
def main(args: Array[String]): Unit = {
val applyTest=ApplyDemo(“ning”,23,0,90) //没有用new,调用了ApplyDemo的apply方法了
println(s"applyTest_name: $applyTest.name") //applyTest_name: day3.ApplyDemo@3c5a99da.name
applyTest match {
//隐式调用了unapply方法,提取若干个参数进行模式匹配
case ApplyDemo(“ning”,age,faceValue) => println(s"age: $age") //age: 23
case _ =>println(“nothing”)
}
}
}
样例类
当一个类被定义成为case类后,Scala会自动帮你创建一个伴生对象并帮你实现了apply, unapply,setter, getter 和toString,equals,copy和hashCode等方法
(1)、什么是apply方法和unapply方法:
首先定义一个类
class MyStudent(val name: String, val age: Int){
def getName(){
println("name is : " + name + "age : " + age )
}
}
实现 apply 方法
object MyStudent{ // 伴生对象 MyStudent,里面定义了apply方法
// apply方法有点类似于java中的构造函数,接受构造参数变成一个对象。
def apply(name: String, age: Int): MyStudent = {
new MyStudent(name, age)
}
}
调用方式,就可以不用写new 了
val m1 = MyStudent("zhangsan", 26) // 由于定义了伴生对象, 可以不用使用new 进行创建对象
m1.getName()
(2)、实现unapply方法:接受一个对象,从对象中提取出相应的值,用来做模式匹配
object MyStudent{ // 伴生对象 MyStudent,里面定义了apply方法
// apply方法有点类似于java中的构造函数,接受构造参数变成一个对象。
def apply(name: String, age: Int): MyStudent = {
new MyStudent(name, age)
}
// unapply方法就刚好相反,他是接受一个对象,从对象中提取出相应的值。 用来最为模式匹配
def unapply(myStudent: MyStudent): Option[(String, Int)] = {
if (myStudent == null){
None
}else{
Some(myStudent.name, myStudent.age)
}
}
}
这时:我们就可以使用模式匹配了:
val m1 = MyStudent("zhangsan", 26) // 由于定义了伴生对象, 可以不用使用new 进行创建对象
m1.getName()
// 结合 unapply方法
m1 match{
case MyStudent("zhangsan_2", _) => println("zhangsan_2")
case _ => println("not such student")
}
所以case class 直接可以使用 val object = ClassDemo() 不用使用new 和直接使用 类的模式匹配了。
(3)、getter 方法和 hashCode方法, toString方法
//构造器的函数默认是public val修饰的,public val name:String
scala> case class Student(name: String, age: Int, studentNum: Int)
defined class Student
scala> Student(“zhangsan”, 24, 1024)
res7: Student = Student(zhangsan,24,1024)
scala> val s = Student(“zhangsan”, 24, 1024)
s: Student = Student(zhangsan,24,1024)
scala> s.age.toString
res8: String = 24
scala> s.hashCode
res9: Int = -1184807636
scala> s.name
res10: String = zhangsan
scala> s.age
res11: Int = 24
scala> s.studentNum
res12: Int = 1024
(4)、 copy() 方法, equals方法
//样例类的拷贝是浅拷贝
scala> val s1 = s.copy()
s1: Student = Student(zhangsan,24,1024)
scala> s1
res13: Student = Student(zhangsan,24,1024)
//样例类的比较是基于值的比较,而不是基于引用,输出true
scala> s==s1
res14: Boolean = true
scala> s equals s1
res15: Boolean = true
(5)、setter方法
由于下面两行代码是对应的,默认是使用 val , 当我们要使用setter 方法时,需要使用var 可变的参数
case class Student(name: String, age: Int, studentNum): Int
case class Student(val name: String, val age: Int, val studentNum): Int
使用setter方法的方式
case class Student(var name: String, var age: Int, var studentNum): Int
// 这时, 我们就可以重新对name 等进行赋值
name = “zhaosi”