apply()与unapply()
apply方法接受构造参数变成对象
- 而
unapply方法接受一个对象,从中提取值
。
apply方法
- 通常,在一个类的伴生对象中定义apply方法,在生成这个类的对象时,就省去了new关键字。
- apply方法会调用伴生类Car的构造方法创建一个Car类的实例化对象
unapply方法
- 可以认为unapply方法是apply方法的反向操作,apply方法接受构造参数变成对象,而unapply方法接受一个对象,从中提取值。
1)当不是new关键字来创建对象的时候,使用apply可以使我们的代码更简洁
class Person {
var name: String = _
var age:Int = 0
}
object Person{
def apply(name:String): Person = {
val person = new Person
person.name = name
person
}
def apply(name:String, age:Int): Person = {
val person = new Person
person.name = name
person.age = age
person
}
}
现在可以不使用new关键字来创建Person对象了
val person2 = Person("Mike")
val person3 = Person("Mary", 23)
- 今天看一下apply、unapply到底是怎样执行,以及其用法!
- 废话不多说,直接来个示例,简单的Persons类里面只有apply方法+Persons伴生对象同样只有apply方法。
- 图1.Persons类andPersons伴生对象
- 上图的打印结果可以看出当代码执行到Persons()时调用了伴生对象的apply方法,而且当我们想输出p对象时,打印的结果为空,所以我们能够得知Person() != new Persons()。那么如果我们在第14行代码中使用 new Persons会是什么结果呢?
- 图2.使用new Class的方式
- 上图中,我们使用new关键字创建了一个对象,并把这个对象的地址打印了出来。但Scala并没有调用class中的apply方法(更不会调用伴生对象中的apply方法)。如果我们想调用class中的apply方法只能new出新对象然后用new出的对象调用!但是我们使用数组Array时并没有使用new关键字,为什么Scala会给我们生成一个对象呢?看下图
- 图3.使用Array构建一个数组
- 很显然,Scala在Array的伴生对象中new出了一个新的Array,具体实现请看源码~~~~~
=====================================================
- 下面看一下我们怎样使用伴生类+apply方法生成指定的对象。假设需求是我们需要通过Persons类的age字段判断这个人是Old Man、Young Man、Strong Man、Others。下面我们看一下代码怎么实现:
- 图4.伴生对象apply方法使用
- 从上图很容易得出——
伴生对象相当于一个工厂类
,根据age大小生成不同类型types的人,上图中val p = Persons(“Rone”,19)的风格是不是和Val arr = new Arrary(“A”,“B”)相同呢!在Scala中这样使用apply方法的地方有很多~简而言之,apply方法类似于Java中的构造函数,接收构造参数生成对象。 - 那么unapply是怎样使用的呢?
apply方法是从伴生对象中给伴生类中的参数赋值,那unapply方法则是伴生对象从伴生类中获取参数,以便生成对象时使用
。看下面的示例更清晰: - 图5.unapply示例一
- 上图中打印出名字就是生成时对象时传参进来的Rone,那么怎样才能触发unapply方法呢?则需要用到模式匹配!需求是如果遇到name为Rone的人则将其名称改为King(自娱自乐勿喷~)接着看代码:
- 图6.模式匹配与unapply方法
- 上图中我得知,unapply方法的触发需要对其对象进行模式匹配,这样我们在模式匹配中能够做更多的操作,且只需要写在伴生类中!
- 希望通过今天的代码能够正确的认识到apply与unapply的区别以及其普遍的用法!最后补充一下Scala中特征类的含义,谢谢!
Unit
- 用于定义返回值类型,它的值只有一个,即"()",它有点类似于Java的void,只不过Java的返回值没有变现形式。
null
- 一般多用于Scala语法赋值时默认的空值,比如:“var blog:String = _”,那么变量中blog的值就为null。
Nothing
- Nothing是Scala语言中所有类的子类,它是没有具体的值的,比如:Nil = List[Nothing]
Option
- 其有两个实现子类,即None和Some两个继承类,None表示不存在,可以给任何数据类型赋值,经查看null的源码case object None extends Option[Nothing]。