Scala类,特征和对象内存分配的差异

时间:2013-11-21 23:07:16

标签: scala

在Scala中,有很多方法可以创建对象:

例如,使用关键字

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

其中car对象应该像堆中的Java座位中的“newed”对象一样,并且在被取消引用时等待垃圾收集。

那么,如何创造特质呢?

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

这是一个有效的语法,使用类myCar扩展Car创建对象。 相反,它只是从Trait创建对象。

它是否反对堆中的座位? (我猜不是) 那么,它是否存在于堆栈中并且一旦从scoop中被取消引用为局部变量?

最后,如何通过对象?

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

这与via Trait相同吗?我相信对象更有可能生活在堆栈中。

有人可以就内存分配方面的这三种语法之间的区别进行阐述吗?

2 个答案:

答案 0 :(得分:7)

他们都住在堆里。 (另外,你的第二个例子没有按照书面形式工作。)

区别在于代码重用。

使用类,该类的每个新对象都运行相同的代码:

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)

使用类(案例1)或实现特征的匿名类(案例2)在内存方面应该是相同的。请注意,您永远不能直接实例化特征。例如,new Car不起作用,只有new Car {}实例化一个扩展该特征的匿名类。

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