scala的样例类和普通类

普通类只有在伴生对象中定义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)

不可变val不能赋值


// 下面, 我们就可以重新对name 等进行赋值,使用setter方法的方式

case class Student(var name: String, var age: Int, var studentNum: Int)
s.name = "zhaosi"

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值