Scala 伴生对象

转载时请以超链接形式标明文章原始出处和作者信息及本声明

http://www.blogbus.com/dreamhead-logs/60217908.html

准备涉水Scala的Java程序员请注意,Scala里没有static

在大多数情况下,static真不该是static的。像Scala这样想在面向对象上更进一步的程序设计语言,取消static是一种进取的表现,这样得以保证了其面向对象模型的完整性。好吧,我承认,??有时候,我们还是需要类一级的属性和操作的。在Scala里,我们还是有机会的,这便是伴生对象(Companion Object)的作用。??

下面就是一个伴生对象的例子:

object Companion {
  def show = println("I am a companion")
}
class Companion {
  def shout = Companion.show
}

(Companion.scala)

这个object就是我们所说的伴生对象,如果读过《走进Scala——Singleton》,你会觉得这个伴生对象和Singleton异曲同工,实际上,是这样的。伴生对象本身就是一个Singleton,不同的是,它有一个与之同名的类(这里的class Companion),二者可以相互访问彼此的私有成员。在这里,我们暂且不关心私有成员的相互访问。

编译一下:

scalac Companion.scala

同Singleton一样,我们也得到了两个文件:Companion.class和Companion$.class。我们还可以用javap查看反编译的结果,其中,Companion$.class与之前的Singleton$.class几近相同,这里就省略了。一起来看看Companion.class。

javap -c Companion

输出为:

Compiled from "Companion.scala"
public class Companion {
  public static void show();
    Code:
       0: getstatic     #16                 // Field Companion$.MODULE$:LCompanion$;
       3: invokevirtual #18                 // Method Companion$.show:()V
       6: return

  public void shout();
    Code:
       0: getstatic     #16                 // Field Companion$.MODULE$:LCompanion$;
       3: invokevirtual #18                 // Method Companion$.show:()V
       6: return

  public Companion();
    Code:
       0: aload_0
       1: invokespecial #24                 // Method java/lang/Object."<init>":()V
       4: return
}

反编译 Companion$,javap -c Companion$

Compiled from "Companion.scala"
public final class Companion$ {
  public static final Companion$ MODULE$;

  public static {};
    Code:
       0: new           #2                  // class Companion$
       3: invokespecial #12                 // Method "<init>":()V
       6: return

  public void show();
    Code:
       0: getstatic     #18                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
       3: ldc           #20                 // String I am a companion
       5: invokevirtual #24                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
       8: return
}

因为有了对应的class,object成了伴生对象。从结果可以看出,伴生对象和它对应的类在字节码层面走到了一起(Companion类)。换句话说,在Scala里面的class和object在Java层面里面合二为一,class里面的成员成了实例成员,object成员成了static成员。我们已经知道,这里的static成员只是一个简单的wrapper,封装了实际的操作。

对应到反编译的代码上,我们看到了与object相关的那个static方法——show。因为要构建Companion的实例,所以,生成的代码里有构造函数。此外,class Companion的实例方法shout在字节码层面上也体现到了Companion类里。

至此,我们已经对伴生对象有了一个基本的了解。在Scala的层面上,我们把分属于类和实例分开放置,从代码的组织而言,会更加清晰。在实现层面上,它们都是按照对象处理的(分别用Companion$和Companion),从而达到了对象模型的统一。

注:

C:\WorkSpace6-scala\scala-train\src\com\usoft>scalac -version

Scala compiler version 2.11.4 -- Copyright 2002-2013, LAMP/EPFL

时间: 2024-10-13 16:21:25

Scala 伴生对象的相关文章

Scala伴生对象

Scala伴生对象 大部分Scala的单例对象不是单独存在的,而是同时存在相同名称的类.此时这个单例对象是"类"的伴生对象,而类则是"单例对象"的伴生类.类与它的伴生对象必须在同一个资源文件内. 例如: case class NumberPair(num1: Int, num2: Int) case class Sum(sumResult: Int) object NumberPair {  implicit def add: NumberPair => Su

scala伴生对象,apply()及单例

1:伴生对象与apply方法 如果一个class与一个object具有相同的名字,那么我们就认为它们互为伴生.object为class的伴生对象.如下图所示,object Apply为class Apply的伴生对象. 需要注意的小细节是,伴生对象的apply函数哪怕没有参数也需要加上一对”()”. class Apply { def apply = { println(" class apply") } def test = println("class test"

聊聊 Scala 的伴生对象及其意义

2019-04-22 关键字:Scala 伴生对象的作用 关于 Scala 伴生对象,比教材更详细的解释. 什么是伴生对象? 教材中关于伴生对象的解释是:实现类似 Java 中那种既有实例成员又有静态成员的类的功能. 为什么上面说它是一种 "功能" 呢?因为要想实现像 Java 中那样的类,光靠一个 Scala 类可不行.在 Scala 中,我们必须: 1. 定义一个 class 并在这里面实现所有的实例成员. 2. 添加一个 object ,这个 object 要与上面的 class

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

010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被其他的类或者对象访问 伴生类访问伴生对象的成员时,要通过名称.成员来访问 调用一些元素的方法初始化创建的时候,例如:Array(1,2,,34,5,6)其实调用了它的apply()方法 欢迎广大爱好者学习交流.也欢迎广大学习爱好者加入 DT大数据梦工厂交流群:462923555 DT大数据微信公众账

快学Scala 第九课 (伴生对象和枚举)

Scala没有静态方法和静态字段, 你可以用object这个语法结构来达到同样的目的. 对象的构造器只有在第一次被使用时才调用. 伴生对象apply方法: 类和它的伴生对象可以互相访问私有特性,他们必须存在于同一个源文件. 类中要访问类的伴生对象中成员,需要通过类.成员调用. class Account private (val id: Int, initialBalance: Double){ } object Account { def apply(initialBalance: Doubl

scala学习手记15 - 独立对象和伴生对象

上一节中的单例对象MarkerFactory 就是一个独立对象的例子.尽管它管理着Marker类,但是它并没有关联到任何类上. scala也可以创建关联到类上的对象.这样的对象同类共享同一个名字,这样的对象称为伴生对象,对应的类就称为伴生类.在scala里,类和伴生对象没有界限,它们互相可以访问彼此的private 方法和private 属性.下面使用伴生对象重写了Marker: class Marker private(val color: String) { println("Creatin

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

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

每天学一点Scala之 伴生类和伴生对象

1.  object 相当于class的单个实例,因此,在object里声明的变量都是静态变量,静态方法 2.  在object里声明的变量,都是全局变量,也就是类的公共属性,或者类似于java中父类的属性 3.  object里的构造器,也就是object 内部不在method中的代码,都属于构造器的内容 4. 同样,object的主构造器只会在第一次调用时执行,多次调用,只会执行一次. object使用场景 1.  单例模式 2.  工具类 伴生对象与 伴生类? 如果有一个class,还有一

转:【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