2013-11-21 122 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 {}实例化扩展该特征的匿名类。

使用单例对象显然只使用该“类”的一个实例。我不认为顶级对象会被垃圾回收,所以你不应该在单例对象中存储大量的数据。