Object和Class区别
1.object与静态类相似,类名加方法直接调用,不用new对象:
Scala比 Java 更面向对象的一个方面是 Scala 没有静态成员。替代品是Scala的单例对象:singleton object。
2.Object()调用的是Object里面的apply方法,val a = new ClassA() a() 调用的是Class里面的apply方法
比如,var traffic=ArrayBuffer("a","b","c") 底层自动调用了apply方法
单例模式分析
使用Java的同学,对单例模式应该很熟悉了,在类的内部声明一个private static 的自身类型的对象,然后通过一个static的方法返回即可。在Scala中,是没有static这个东西的,但是它也为我们提供了单例模式的实现方法,那就是 object(别混了,不是万物之根的object)
Scala中使用单例模式时,除了定义的类之外,还要定义一个同名的object对象,它和类的区别是,object对象不能带参数,先看一段实现代码
/**这是我们定义的类
构造函数被我们定义为private的,防止直接调用该类的构造来创建对象
*/
class StaticTest private {
private def add_(x: Int, y: Int): Int = {
return x + y
}
private def sub_(x: Int, y: Int): Int = {
return x + y
}
}
/**这个就是单例模式的定义,和类同名,且不带参数*/
object StaticTest{
//内部声明一个StaticTest类实例对象
val singleObj = new StaticTest
//applay方法,当执行 StaticTest() 时被执行
def apply()={
println("-------apply--------")
}
def add(x:Int,y:Int):Int={
//调用StaticTest 类的方法
return singleObj.add_(x,y)
}
//调用StaticTest 类的方法
def sub(x:Int,y:Int):Int ={
return singleObj.sub_(x,y)
}
defmain(args:Array[String]):Unit={
//定义一个单例对象
val test=ObjectTest
//调用add方法
println(test.add(2,3))//5
}
}
这个类编译后,会生成两个文件StaticTest.class和StaticTest$.class,class和object被编译到了一起
我们看一下StaticTest$.class类的反编译结果,和我们的Java的单例模式就非常相似了。
public final class StaticTest$
{
//指向自己,外部都通过MODULE$访问接口
public static final MODULE$;
//自身类型的内部静态变量
private final StaticTest singleObj;
static
{
new ();
}
//这个就是对外接口,返回单例对象,很像我们经常用的getInstance
public StaticTest singleObj()
{
return this.singleObj;
}
public int apply() {
Predef..MODULE$.println("-------apply--------");
}
public int add(int x, int y) {
return singleObj().scala$test$StaticTest$$add_(x, y);
}
public int sub(int x, int y) {
return singleObj().scala$test$StaticTest$$sub_(x, y);
}
//私有的构造
private StaticTest$() {
//指向自己
MODULE$ = this;
//创建对象
this.singleObj = new StaticTest();
}
}
再看看StaticTest.class的反编译结果
public class StaticTest
{
public static int sub(int paramInt1, int paramInt2)
{
return StaticTest..MODULE$.sub(paramInt1, paramInt2);
}
public static int add(int paramInt1, int paramInt2)
{
return StaticTest..MODULE$.add(paramInt1, paramInt2);
}
public static void apply()
{
StaticTest..MODULE$.apply();
}
public static StaticTest singleObj()
{
return StaticTest..MODULE$.singleObj();
}
public int scala$test$StaticTest$$add_(int x, int y)
{
return x + y;
}
public int scala$test$StaticTest$$sub_(int x, int y) {
return x + y;
}
}
static方法内通过MODULE$去访问对外接口,也就是StaticTest$中的方法
经过上面分析,可以得知
1.单例对象会在第一次被访问的时候初始化。
2.Scala中的单例模式,除了定义的类之外,还要定义一个同名的object对象
3.同名称为“伴生” ,object是class的伴生对象,class是object的伴生类