本帖最后由 pig2 于 2016-11-29 19:03 编辑
问题导读
1.什么情况下调用apply方法?
2.apply你认为有哪些作用?
3.方法调用属于apply什么功能?
apply网上很多资料,但是总感觉总讲的不是很透彻。这里自己总结下:包括摘录及个人经验,希望可以加深大家的理解
什么情况下会调用apply方法
当遇到下面表达式时,apply方法会被调用:Object(参数1,参数2。。。。参数N)
通常这样一个方法返回的是伴生对象。
举例来说:Array对象定义了apply,我们可以用下面形式来数组
Array("about”,"yun","com")
为什么不使用构造器?对于嵌套式表达式而言,省去new关键字方便很多,例如
Array(Array("about","yun"),Array("www","com"))
我们比较容易搞混
Array("about","yun")与new Array("about","yun")
表面是多了一个new,他们的原理是不同的。
第一个调用的apply方法
第二个调用的this构造器
理解apply方法:实例化作用
这里一个定义apply方法的示例
class Account private (val id: Int, initaBalance: Double){
private var balance = initaBalance
}
Object Account//伴生对象
{
def apply( initaBalance: Double)=new Account (newUniqueNumber(),initalBalance)
}
这样就可以通过apply创建对象了。
val acct=Account (1000.0)
我们在来看一个例子
package aboutyun.com
class ApplyTest{
def apply()=println("I want to speak good english !")
def haveATry: Unit ={
println("Have a try on apply")
}
}
object ApplyTest{
def apply()={
println("I am a student of KMUST")
new ApplyTest
}
}
//驱动函数
object ApplyOperation {
def main(args:Array[String]): Unit ={
//调用伴生对象的apply方法,实例化
val a=ApplyTest()
a.haveATry
}
}
上面我们可以先忽略类的apply方法,只看伴生对象的apply方法。也就是说伴生对象的apply方法简化了对象的实例,一般对象的实例化是
A a=new A();
有了apply,我们可以这样
A a=A();
同样对应起来
val a=new ApplyTest()
有了apply,可以这样
val a=ApplyTest(),其实它是是val a=ApplyTest.apply()的简化。
从这里我们再次得出,只要是我们使用apply实例化的类,必定有伴生对象。
(补充:Scala中同名和类和对象分别称之为伴生类和伴生对象)
为了加深理解,我们在换另外一个说法
半生对象中有一个apply方法
构造类的时候一般不用new A()
上面不知你是否理解,这样我们在反过来,假如一个类,没有伴生对象,能否使用使用A a=A();的方式。
显然这样是不行的。但是在Scala中,很多类默认都是由伴生对象的,所以我们可以简化类的实例。这样apply方法你是否理解了。
对象调用apply方法
apply除了实例化作用,我们看到实例化的对象,还可以a();这样,这时候调用的是类的apply方法,而非伴生对象的。
package aboutyun.com
class ApplyTest{
def apply()=println("I want to speak good english !")
def haveATry: Unit ={
println("Have a try on apply")
}
}
object ApplyTest{
def apply()={
println("I am a student of KMUST")
new ApplyTest
}
}
//驱动函数
object ApplyOperation {
def main(args:Array[String]): Unit ={
//调用伴生对象的apply方法,实例化
val a=ApplyTest()
a.haveATry
a();
}
}
##############################
通过上面我们的理解,我们来看下下面的内容:
[mw_shl_code=scala,true]scala> val f = (x: Int) => x + 1
f: Int => Int = <function1>[/mw_shl_code]
改如何调用函数对象的方法
[mw_shl_code=scala,true]scala> f.apply(3)
[/mw_shl_code]
上面为何能这么做,这是因为函数也是对象,, 每一个对象都是scala.FunctionN(1-22)的实例。每次调用方法对象都要通过FunctionN.apply(x, y...), 就会略显啰嗦, Scala提供一种模仿函数调用的格式来调用函数对象
[mw_shl_code=scala,true]scala> f(3)
res3: Int = 4[/mw_shl_code]
上面其实就是scala.FunctionN的对象。f(3),就是 f.apply(3)
#############################################
apply方法具有查找属性
集合类
在Scala集合一文中提到过Iterator迭代器的几个子trait包括Seq, Set, Map都继承PartialFunction并实现了apply方法, 不同的是实现的方式不一样,
也就是说如果前面是集合,后面使用apply,则具有查找功能
[mw_shl_code=scala,true]scala> Seq(1, 2, 3).apply(1) // 检索
res6: Int = 2
scala> Set(1, 2, 3).apply(2) // 判断是否存在
res7: Boolean = true
scala> Map("china" -> "beijing", "US" -> "Washington").apply("US") // 根据键查找值
res8: String = Washington
scala> Set(1, 2, 3)(2)
res9: Boolean = true
scala> Set(1, 2, 3)(2)
res10: Boolean = true
scala> Map("china" -> "beijing", "US" -> "Washington")("US")
res11: String = Washington[/mw_shl_code]
总结:
从上面总结:
apply方法具有三个作用
1.具有实例化的作用
2.实例化对象可以再次调用apply方法
3.apply在集合中具有查找作用
|
|