Scala:object(单例)

Scala开篇(目录)

使用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)
  }
}

使用

    //定义一个单例对象
    val test = StaticTest
    //调用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--------");
    return add(3, 4); }

  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$去访问接口

上面是在单例中访问同名类实例中的方法,那如果在单例中有一个类,在外部类中要使用该怎样呢?

class StaticTest private {
  def getInner() : Inner = {
    new Inner
  }
}
object StaticTest{
  class Inner{

  }
}

我们要在类StaticTest中使用单例StaticTest中的Inner类,按照上面的代码,是会提示错误的,提示你找不到Inner类,要想使用它,可以按照下面的方式:

方式一:

//类的外部引入
import scala.test.StaticTest.Inner
class StaticTest private {
  def getInner() : Inner = {
    new Inner
  }
}
object StaticTest{
  class Inner{

  }
}

方式二:

class StaticTest private {
//在类的内部引用
  import StaticTest._
  def getInner() : Inner = {
    new Inner
  }
}
object StaticTest{
  class Inner{

  }
}
时间: 2024-10-06 19:55:19

Scala:object(单例)的相关文章

Scala的单例对象

通常,一个类对应一个伴生对象,其方法就跟Java中的静态方法一样,举例:BigInt类的BigInt伴生对象有一个生成指定位数的随机素数的方法probablePrime,在REPL中运行下列代码: object HelloWorld{ def main(args:Array[String]){ for( i<- 1 to 10){ println(BigInt.probablePrime(10,scala.util.Random)); } } } 得到的结果如下: 523 977 839 911

【Scala】单例对象与伴生对象

Scala的单例对象 Scala不能定义静态成员,而是代之定义单例对象(singleton object).以object关键字定义. 对象定义了某个类的单个实例,包含了你想要的特性: object Accounts{ private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNumber} } 当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可. 对象的构造

转:【Scala】单例对象与伴生对象

转自:http://blog.csdn.net/jasonding1354/article/details/46507595 Scala的单例对象 Scala不能定义静态成员,而是代之定义单例对象(singleton object).以object关键字定义. 对象定义了某个类的单个实例,包含了你想要的特性: object Accounts{ private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNum

Scala学习 -- 单例对象

Scala 比 Java 更面向对象一点,是 Scala 的类不允许静态(static)成员.对此类使用场景,Scala 提供了 单例对象(object).单例对象的定义看上去跟类定义很像,只不过 class 关键字被换成了 object 关键字. 在事例中单例对象名叫 ChecksumAccumulator, 跟前一个例子中的类名一样. 当单例对象跟某个类公用同一个名字时,它被称作这个类的 伴生对象(companion object). 必须在同一个源码文件中定义的类和类的伴生对象.同时,类又

Scala 单例对象

环境: CentOS 6.3, eclipse 单例对象:类是指用class定义的scala 对象,如果用object替换class关键字,那么这个就叫单例对象,sigleton object, 单例对象不可以使用new 关键字生成新的对象实例下面使用三种使用校验和的方式来解释大家的疑问. ChecksumAccumulator.scala //定义class(类) ChecksumAccumulator 和其伴生单例对象(object) ChecksumAccumulator package

设计模式:简单工厂和单例工厂

1 <?php 2 /** 3 * 纯粹工厂类 4 */ 5 /*class Factory { 6 public static function getOBJ($class_name) { 7 include_once './'.$class_name.'.class.php'; 8 return new $class_name; //可变类 9 } 10 } 11 */ 12 13 /** 14 * cun工厂类 15 */ 16 class Factory { 17 /* 18 生产单例对

scala学习手记14 - 单例对象

java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例.在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可.因为单例类无法初始化,所以不能向它的主构造函数传递参数. 下面是一个单例的示例: class Marker(val color: String) { println("Creating " + this) override def toString(): String = "marker color " + colo

scala 单例、伴生对象、伴生类

单例:使得对象成为系统中的唯一实例 package scala object single { private var sno:Int = 3; def singlesno()={ sno += 1 sno } } object singleTest { def main(args: Array[String]): Unit = { println(single.singlesno()) println(single.singlesno()) } } 伴生对象: 当单例对象与某个类共享同一个名称

Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式

package com.parllay.scala.bestpractive import scala.reflect.runtime.universe import scala.reflect.runtime.universe.typeOf import com.parllay.scala.bestpractive.Scala /** * Created by richard on 15-9-5. * 第79讲:单例深入讲解及单例背后的链式表达式 */ object Scala class J