15 apply和unapply方法
apply、unapply方法都被隐式的调用
apply方法:
1)在一个类的伴生对象中定义apply方法,在生成这个类的对象时,就省去了new关键字。
2)apply方法的参数列表不需要和构造函数的参数列表统一,也就是说apply 方法支持重载。
3)apply 方法可以通过主构造器和辅助构造器new对象;
4)apply方法 定义在object 里,是创建对象;如果定义在class 里,是获取对象的数据;
apply方法定义在object对象
package day03
class ApplyDemo(val name:String) {
var age:Int = _
def this(name:String, age:Int) = {
this(name)
this.age = age
}
}
object ApplyDemo{
// 在 object对象上定义apply方法是用来创建对象的
// 调用主构造器创建对象
def apply(name: String): ApplyDemo = {
println("==> apply(name: String)")
new ApplyDemo(name)
}
// 调用辅助构造器创建对象
// apply方法是可以重载的
def apply(name: String, age:Int): ApplyDemo = {
println("==> apply(name: String, age:Int)")
new ApplyDemo(name, age)
}
def main(args: Array[String]): Unit = {
// 直接new对象
val demo = new ApplyDemo("hainiu")
// 通过scala隐式的调用apply方法(主构造器)创建对象,此时不需要new关键字
val demo2 = ApplyDemo("hainiu")
println(demo2.name)
// 通过隐式调用apply方法(调用的辅助构造器)来创建对象
val demo3 = ApplyDemo("hainiu", 10)
println(s"${demo3.name}, ${demo3.age}")
}
}
apply方法定义在class上
package day03
class ApplyDemo2 {
private val list = List(1,5,2,3,6,7)
// apply 方法定义在class上是用来提取数据的
// 就相当于数组、列表提取数据一样
def apply(index:Int) = {
this.list(index)
}
}
object ApplyDemo2{
def main(args: Array[String]): Unit = {
val demo = new ApplyDemo2
println(demo.apply(0))
println(demo(0))
}
}
unapply方法:
1)可以认为unapply方法是apply方法的反向操作,apply方法接受构造参数变成对象,而unapply方法接受一个对象,从中提取值。
2)unapply方法常被称为提取方法,可以用unapply方法提取相同操作的对象,unapply方法会返回一个Option,其内部生成一个Some对象,这个Some是做相似对象的封装。
3)unapply 不支持重载。
4)unapply常被用于模糊匹配。
Option
Option中的泛型个数影响unapply方法返回some参数的个数和模式匹配中的case类型参数的个数。
Option 子类:
None:无数据,scala 用None 来表达 无数据, 相当于java 的 null
Some:有数据。
用的地方:
1)模式匹配
2)集合
package day03
class UnapplyDemo(val name:String, val age:Int) {
}
object UnapplyDemo{
// unapply方法是用来解构的
// 你给我对象,我把对象里的数据提取出来(通过模式匹配)
def unapply(arg: UnapplyDemo): Option[(String, Int)] = {
println("==> unapply(arg: UnapplyDemo): Option[(String, Int)]")
Some((arg.name, arg.age))
}
// unapply方法不能重载
// def unapply(arg: UnapplyDemo): Option[String] = {
// println("==> unapply(arg: UnapplyDemo): Option[(String, Int)]")
// Some(arg.name)
// }
def main(args: Array[String]): Unit = {
val demo = new UnapplyDemo("hainiu", 10)
demo match{
// type1: 由于是直接匹配对象,所以不需要走unapply方法
// case x : UnapplyDemo => println(s"type1==>${x.name}, ${x.age}")
// 下面的都是提取对象里面数据的,这些都走unapply方法
case UnapplyDemo(x,y) => println(s"type2==>${x}, ${y}")
case UnapplyDemo(x) => println(s"type3==>${x._1}, ${x._2}")
case UnapplyDemo("hainiu", y) => println(s"type4==>hainiu, ${y}")
}
}
}
总结:
apply 方法定义 object 中,用于创建对象;
apply方法定义 class 中, 用于提取数据;
unapply 方法 定义在 object 对象中, 用于提取对象数据;