@
说在前面
- scala是纯面向对象的语言,C是纯面向过程的语言,Java就是面向过程+面向对象的语言。
- 在说到伴生对象之前,要先说到java的
static
关键字,static关键字修饰的变量、方法可以使类对象共享,而非某个对象单独拥有,所以是通过类名.变量名/方法名
去调用。而这违背了scala面向对象的初衷,因为这没有通过对象去调用。
运行原理
scala的编译与java大同小异:
-
Java运行原理
- 先编译,再解释
- .java源文件--->编译器(javac)--->.class字节码文件--->JVM(java 不同平台)--->机器指令
-
Scala运行原理
- 先编译,再解释
- .scala源文件--->编译器(scalac)--->.class字节码文件--->JVM(scala 不同平台)--->机器指令
代码体现
观察下面这段代码,Scala01_HelloWorld.scala
object Scala01_HelloWorld {
def main(args: Array[String]): Unit = {
println("HelloScala")
}
}
经过编译后,可以看见,scala文件编译成了两个.class文件
使用反编译工具打开看看它们:
Scala01_HelloWorld.class,伴生类
package com.sun.scala.chapter01;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes=" 06 01):Q! 01 02 02- 21cU2bY 06 04 24g 30%fY2|wk 34:e 25 31A!A 05dQ 06 04H/ 32:1c) 21QAB 01 06g 16fG. 31 06 03 17! 1a];o 25 05I 21aA2p[ 16 01 01C 01 07 16 33 05 21a! 02 03 21 03y!!E*dC2f 07'M0IK2dwnV8sIN 21Q 02 05 03#Mi 21A 05 06 02 13% 21AC 05 02 07 03:L(+ 324 13YiA 21Af 02
qJg. 33;?) 05Y 01"B
16 03Q 22 01B7bS:$"a 07 20 21 05Ea 22BA 17 23 05 21)f. 33; 13}A 02 31 01 21 02 05 24xm 35 04# 05 32 23B 01 22 23 05 25 %O]1z! !sE 04 02 22K% 21aEE 01 07!J,G- 324
05!J#AB*ue&twM 03 02'% 01")
public final class Scala01_HelloWord
{
public static void main(String[] paramArrayOfString)
{
Scala01_HelloWord..MODULE$.main(paramArrayOfString);
}
}
Scala01_HelloWorld$.class,伴生对象所属类
package com.sun.scala.chapter01;
import scala.Predef.;
public final class Scala01_HelloWord$
{
public static final MODULE$;
static
{
new ();
}
public void main(String[] args)
{
Predef..MODULE$.println("hello,scala");
}
private Scala01_HelloWord$()
{
MODULE$ = this;
}
}
解析
object 名称
从语法角度讲,上面语法表示声明了一个伴生对象
Scala是纯面向对象的,去除了java中的static关键字,通过伴生对象模拟static的效果(类名.变量名/方法名
)- 伴生对象
- 伴随着某个类产生的一个对象
- 当我们对源文件进行编译之后,默认会生成两个字节码文件,一个是伴生类,另一个是伴生对象所属类
- 真正的伴生对象是伴生对象所属类中创建的单例对象
- 如果不想默认生成伴生类,可以手动生成,要求伴生类名称和伴生对象名称一致
- 所以在scala程序中,如果要想实现static效果,那么我们应该使用
object
关键字将属性以及方法定义在伴生对象类中