Object和Class區別
1.object與靜態類相似,類名加方法直接調用,不用new對象:
Scala比 Java 更面向對象的一個方面是 Scala 沒有靜態成員。替代品是Scala的單例對象:singleton object。
2.Object()調用的是Object裏面的apply方法,val a = new ClassA() a() 調用的是Class裏面的apply方法
比如,var traffic=ArrayBuffer("a","b","c") 底層自動調用了apply方法
單例模式分析
使用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)
}
defmain(args:Array[String]):Unit={
//定義一個單例對象
val test=ObjectTest
//調用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--------");
}
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$去訪問對外接口,也就是StaticTest$中的方法
經過上面分析,可以得知
1.單例對象會在第一次被訪問的時候初始化。
2.Scala中的單例模式,除了定義的類之外,還要定義一個同名的object對象
3.同名稱爲“伴生” ,object是class的伴生對象,class是object的伴生類