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