2013-11-21 153 views
2

在Scala中,有許多方法來創建對象:差異斯卡拉類,特質和對象的內存分配

例如,通過類關鍵字生成

class Car { 
    def startEngine() = println("run....") 
} 
val car = new Car 
car.startEngine() // run.... 

其中汽車對象應該採取行動就像Java中的「newed」對象在堆中一樣,等待被垃圾收集,因爲它被取消引用。

那麼,如何創建雖然特質?

trait Car { 
    def startEngine() = println("run...") 
} 
val car = new Car {} 
car.startEngine() //run.... 

這是使用class myCar擴展Car創建對象的有效語法。 相反,它只是從Trait創建對象。

它是否對象堆中的座位? (我想不是) 那麼,它是否生活在堆棧中,並且會被取消引用爲局部變量,一旦出現問題?

最後,如何通過對象?

object Car { 
    def startEngine() = println("run...") 
} 
Car.startEngine() //run.... 

這是通過特質相同的情況?我相信對象更有可能生活在堆棧中。

請問有人可以從內存分配的角度闡明這三種語法之間的區別?

回答

6

他們都住在堆裏。 (另外,您的第二個示例沒有像寫入那樣工作。)

區別在於代碼重用。

有了一個類,這個類的每個新對象運行相同的代碼:

class Car { } 
val c1 = new Car 
val c2 = new Car // Same code as c1 
c1.getClass == c2.getClass // true 
c1 eq c2     // false--different objects on the heap 

與性狀,每次你從它做一個類時,它複製的代碼(至少轉發)。所以它效率較低但更靈活(因爲您可以在需要時將其混合到其他類中)。並且你可以通過添加{}爲每個對象一個新的匿名類,所以可以很容易地做了很多工作,白白:

trait Car { } 
val t1 = new Car {} // Anon class #1 
val t2 = new Car {} // Anon class #2--duplicate of #1 
t1.getClass == t2.getClass // false 

一個對象,你明確地說,有將是唯一的一個。你不能(沒有低級別的詭計)得到另一個。

object Car { } 
val o1 = Car 
val o2 = Car 
o1 eq o2  // true -- there is only one Car 
1

使用類(情況1)或實現特徵(情況2)的匿名類在內存方面應該是相同的。請注意,你永遠不能直接實例化特質。例如,new Car將不起作用,但只有new Car {}實例化擴展該特徵的匿名類。

使用單例對象顯然只使用該「類」的一個實例。我不認爲頂級對象會被垃圾回收,所以你不應該在單例對象中存儲大量的數據。