研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备。

static不是keyword

上一篇文章提到过,interface并非Scala语言keyword,能够自由使用。

相同,static在Scala里也没有特殊的含义,也是能够自由使用的,如以下代码所看到的:

单例对象

Java并非完美的面向对象语言,包含非常多缺陷,比方同意static字段和方法,primitive类型。等等。Scala语言在这些方面都有所改进。所以号称是比Java更OO的语言。

既然去掉了statickeyword,那么怎样像Java语言那样。表达类字段类方法呢?Scala给出的解决方式是:单例对象。Java有一个Math类(java.lang.Math),里头全是static字段和方法,部分代码例如以下所看到的:

public final class Math {

    private Math() {} // Don't let anyone instantiate this class.

    public static final double PI = 3.14159265358979323846;

    public static int abs(int a) {
return (a < 0) ? -a : a;
} }

以下我们用Scala语言重写上面的Math类:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhob28=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

单例对象实现方式

以下看看Scala是怎样实现单例对象的。观察编译结果能够看到,MyMath被编译出两个class:MyMath.classMyMath$.class。我自己分析了一下这两个class,以下是MyMath.class的反编译结果:

public final class MyMath {

    public static double PI() {
return MyMath$.MODULE$.PI();
} public static int abs(int a) {
return MyMath$.MODULE$.abs(a);
} }

能够得出例如以下结论:

  1. val字段实际上也被编译成了方法
  2. 两个方法都是static,并且仅仅是调用MyMath$.MODULE$的对应方法

再来看MyMath$.class的反编译结果:

public final class MyMath$ {

    public static final MyMath$ MODULE$;
private final double PI; static {
new MyMath$();
} private MyMath$() {
MyMath$.MODULE$ = this;
this.PI = 3.14;
} public double PI() {
return this.PI;
} public int abs(int a) {
return return (a < 0) ? -a : a;
} }

就是普通的单例模式,这肯定也就是单例对象这一名称的由来。

使用单例对象

以下这段代码演示了怎样使用单例对象:

看起来和使用Java静态字段或方法没啥差别,以下是反编译之后的main方法代码:

Predef$.MODULE$.println("PI is " + MyMath$.MODULE$.PI())
final int x = -18
final int y = MyMath$.MODULE$.abs(x)

伴随类和伴随对象

上面的样例中,我们定义了名为MyMath的单例对象,实际上。这并最好还是碍我们定义同名的

例如以下所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhob28=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

这样的情况下,单例对象叫做同名类的Companion Object。类叫做单例对象的Companion Class

假设仅定了单例对象。但未定义同名的类。那么这样的情况下单例对象被叫做Standalone Object

注意:Companion Class和Object必须定义在同一个.scala文件中。

探索Scala(3)-- 单例对象的更多相关文章

  1. Scala单例对象、伴生对象实战详解

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

  2. Scala单例对象和伴生对象

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

  3. Scala入门1(单例对象和伴生类)

    一.Hello World程序的执行原理 参考http://blog.csdn.net/zhangjg_blog/article/details/22760957 object HelloWorld{ ...

  4. scala学习手记14 - 单例对象

    java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例.在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可.因为单例类无法初始化,所以不能向它的主构造函数传 ...

  5. 【scala】类的定义和单例对象

    一.类的定义 Scala类的定义跟JAVA中类的定义基本是一样的. 示例 class ChecksumAccumulator{ var sum = 0;//Scala默认关键字为public priv ...

  6. Scala 孤立对象和单例对象方法体的用法和例子

    [学习笔记] 1  以object关键字修饰一个类名,这种语法叫做孤立对象,这个对象是单例的. 相当于将单例类和单例对象同时定义.相当于java中的单例,即在内存中只会存在一个Test3实例.创建一个 ...

  7. Spring IoC 中的(Singleton)单例对象创建过程探索

    前言 之前将spring framework 源码导入了idea,后来折腾调试了一下,于是研究了一下最简单的singleton对象在spring中是如何创建的.这里所谓的简单,就是指无属性注入,无复杂 ...

  8. 010-Scala单例对象、伴生对象实战详解

    010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被 ...

  9. apply 伴生对象 单例对象

    apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object F ...

随机推荐

  1. AbstractFactory(抽象工厂模式)

    AbstractFactory(抽象工厂模式) 有些情况下我们需要根据不同的选择逻辑提供不同的构造工厂,而对于多个工厂而言需要一个统一的抽象 <?php class Config { publi ...

  2. Charlie's Change(完全背包记录路径)

    Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffe ...

  3. TOJ 2541: Paper Cutting

    2541: Paper Cutting  Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByteTotal Submit: ...

  4. java面向抽象编程样例

    import java.util.*; abstract class Geometry{    public abstract double getArea();    }  class Pillar ...

  5. HackerRank# Bricks Game

    原题地址 DP很简单,懒得压缩空间了,反正都能过 #include <cmath> #include <cstdio> #include <vector> #inc ...

  6. Spoj-BLMIRINA Archery Training

    Mirana is an archer with superpower. Every arrow she shoots will get stronger the further it travels ...

  7. KVM 存储虚拟化

    KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的. Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种类型,后面会详细讨论.Volume 是 ...

  8. golang文件下载断点续传(下载客户端)

    客户端: //const ( // UA = "Golang Downloader from Kejibo.com" //) func DownloadController(ctx ...

  9. Oracle 12c PDB和CDB全局用户权限问题

    Oracle12c版本中引入了新的CDB和PDB 默认登陆CDB后创建的用户为全局用户必须以c##开头 如果要访问CDB中的表,可以用GRANT命令赋权 但是上面的赋权并不会再PDB中生效 如果要这个 ...

  10. Set 技巧之一

    我们知道set中 用set<int,int>S; S.lower_bound(x): 查找Set中 第一个>=x的数,返回结果是指针. S.upper_bound(x):查找Set中 ...