- 在Scala中定义类是用class关键字;
class HelloOOP {
var name = "Spark"
def sayHello = println("Hi, My name is " + name)
}
- 可以使用new ClassName的方式构建出类的对象;
val helloOOP = new HelloOOP
helloOOP.sayHello
- 如果名称相同,则object中的内容都是class的静态内容,也就是说object中的内容class都可以在没有实例的时候直接去调用;正因为可以在没有类的实例的时候去调用object中的一切内容,所以可以使用object中的特定方法来创建类的实例,而这个特定方法就是apply方法;
- object中apply方式是class对象生成的工厂方法,用于控制对象的生成;
def apply(): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP
}
- 很多框架的代码一般直接调用抽象类的object的apply方法去生成类的实例对象;
第一:其秘诀在于apply具有类的对象生成的一切生杀大权,抽象类是不可以直接实例化的,在apply方法中可以实例化抽象类的 子类,以Spark中图计算为例,Graph是抽象的class,在object Graph中的apply方法实际上是调用了Graph的子类GraphImpl来构建Graph类型的对象实例的,当然从Spark图计算的源码可以看出,GraphImpl的构造也是使用了object GraphImpl的apply方法;
第二:这种方式神奇的效应在于更加能够应对代表版本迭代或者修改的变化,这是更高意义的面向接口编程;
- 很多框架的代码一般直接调用抽象类的object的apply方法去生成类的实例对象;
- object HelloOOP是class HelloOOP的伴生对象,class HelloOOP可以直接访问object HelloOOP中的一切内容,而class HelloOOP是object HelloOOP的伴生类,object HelloOOP可以直接访问class HelloOOP的一切内容,一个特例是用private[this]修饰的成员;
- 在定义Scala的class的时候可以直接在类名后面()里加入类的构造参数,此时在apply方法中也必须有这些参数;
def apply(age:Int): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP(age)
}
- Scala中可以的在object中构造很多apply方法;
def apply(age:Int): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP(age)
}
def apply(): HelloOOP = {
println("Without age, My number is : " + number)
number += 1
new HelloOOP(10)
}
- Scala中的很多集合都是使用apply的方式构造的,例如Array:
/** Creates an array of `Int` objects */
// Subject to a compiler optimization in Cleanup, see above.
def apply(x: Int, xs: Int*): Array[Int] = {
val array = new Array[Int](xs.length + 1)
array(0) = x
var i = 1
for (x <- xs.iterator) { array(i) = x; i += 1 }
array
}
完整的实例:
object HelloOOP {
var number = 0
def main(args: Array[String]): Unit = {
println("Hello Scala OOP!!")
//val helloOOP = new HelloOOP
val helloOOP = HelloOOP(30)
helloOOP.sayHello
HelloOOP()
HelloOOP()
HelloOOP()
HelloOOP()
HelloOOP()
HelloOOP()
}
def apply(age:Int): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP(age)
}
def apply(): HelloOOP = {
println("Without age, My number is : " + number)
number += 1
new HelloOOP(10)
}
}
class HelloOOP(age:Int) {
var name = "Spark"
def sayHello = {
println("Hi, My name is " + name)
println("My age is " + age)
}
}