Scala:Object单例模式分析

ObjectClass区别

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的伴生类

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值