前言
scala作为面向对象语言,有很多独特的黑科技,下面介绍一个黑科技用法!将对象当做函数来进行调用!下面通过一些案例来进一步阐述这个用法!
code
package com.zhengkw.single
/**
* Author zhengkw
* Date 2020/4/25 10:37
*/
object ApplyDemo1 {
def main(args: Array[String]): Unit = {
A() // 等价于 A.apply()
A.apply()
val a = new A
a()
(foo _).apply(10)
}
def foo(a:Int) = println("foo...")
}
object A{
def apply() = println("A... apply")
}
class A{
def apply() = println("class A ... apply")
}
A... apply
A... apply
class A ... apply
foo...
特别注意
注意通过伴生对象调用apply方法或者伴生对象()
都会调用伴生对象中的apply方法!
而通过new出来的 对象调用apply方法会执行伴生类中的apply方法!
而没有声明过apply方法的对象调用的scala提供的apply方法!
因为我(foo _)转为函数后只是传入了一个参数,所以调用的fun1里的apply方法。如果参数为N则调用funN的apply方法!
一般用法
一般apply是用于实例化对象使用!即在工厂类使用!以下介绍一些关于apply的注意事项
- 其实函数也可以通过apply进行调用. (方法不行), 如果是方法, 先把方法转成函数(使用下划线!)再使用.
- 伴生对象的
apply
, 通常情况是返回伴生类的对象, 然后在外面创建对象的时候, 可以省略new
- 普通类中的
apply
, 一般根据具体的业务逻辑来实现.apply
也可以重载
package com.atguigu.scala1128.day05.single
/**
* Author atguigu
* Date 2020/4/25 11:17
*/
object ApplyDemo2 {
def main(args: Array[String]): Unit = {
val user = User("lisi", 20); // User.apply("lisi", 20)
println(user)
val arr = new MyArray(10,20,30,40)
println(arr(0)) // arr.apply(0)
println(arr(1))
}
}
class MyArray(val args: Int*){
def apply(index: Int) = args(index)
}
object User {
var a = 10
def apply(name: String, age: Int) = new User(name, age)
}
class User(val name: String, var age: Int){
var a = 100
override def toString: String = s"$name, $age, ${User.a}" //打印的是伴生对象里的a
}
lisi, 20, 10
10
20
总结
- 方法名必须是apply!!!
- 伴生对象调用的apply方法是在伴生对象中声明的!
- new出来的对象调用的是类中的apply方法!
- apply方法也支持重载!