什么是使用new运算符VS通过扩展类中定义一个独立的对象定义对象之间的区别?
更具体地讲,是给定类型class GenericType { ... }
之间的区别是什么val a = new GenericType
和object a extends GenericType
?
什么是使用new运算符VS通过扩展类中定义一个独立的对象定义对象之间的区别?
更具体地讲,是给定类型class GenericType { ... }
之间的区别是什么val a = new GenericType
和object a extends GenericType
?
作为一个实际问题, object
声明初始化相同的机制作为new
的字节码。 但是,也有相当多的不同之处:
object
作为单身-每个属于其中只有一个实例存在的类; object
被延迟初始化-它们将只创建/初始化时首先提到; object
和一个class
(或trait
的同名)是同伴 ; object
产生的伴侣静态代理class
; object
可以访问同伴的私有成员class
; 这些只是一些我能想到蝙蝠的权利的差异。 有可能是别人。
*什么是“相关”类或性状是一个较长的故事 - 查找解释它,如果你有兴趣的堆栈溢出的问题。 看看wiki上scala
的标签,如果你很难找到他们。
对象定义(无论扩展的东西与否)是指单对象的创建。
scala> class GenericType
defined class GenericType
scala> val a = new GenericType
a: GenericType = GenericType@2d581156
scala> val a = new GenericType
a: GenericType = GenericType@71e7c512
scala> object genericObject extends GenericType
defined module genericObject
scala> val a = genericObject
a: genericObject.type = genericObject$@5549fe36
scala> val a = genericObject
a: genericObject.type = genericObject$@5549fe36
虽然object
声明具有比一个不同的语义new
表达,一个本地object
的声明是所有意图和目的,同样的事情,作为一个lazy val
同名。 考虑:
class Foo( name: String ) {
println(name+".new")
def doSomething( arg: Int ) {
println(name+".doSomething("+arg+")")
}
}
def bar( x: => Foo ) {
x.doSomething(1)
x.doSomething(2)
}
def test1() {
lazy val a = new Foo("a")
bar( a )
}
def test2() {
object b extends Foo("b")
bar( b )
}
test1
定义a
作为懒惰VAL用的新实例被初始化Foo
,而test2
定义b
作为object
延伸Foo
。 从本质上讲,无论是懒洋洋地创建一个新的实例Foo
并给它一个名称( a
/ b
)。
你可以尝试在REPL并验证它们都具有相同的行为:
scala> test1()
a.new
a.doSomething(1)
a.doSomething(2)
scala> test2()
b.new
b.doSomething(1)
b.doSomething(2)
因此,尽管之间的语义差异object
和lazy val
(在特定的特殊处理object
由该语言的,如所概述的丹尼尔C.索布拉尔),一个lazy val
总是可以与相应的取代的object
(未,它是一个非常好的做法),和同样的lazy val
/ object
是一类/特质的成员。 我能想到的主要实际差异将对象具有一个更具体的静态类型: b
是类型的b.type
(其延伸Foo
),而a
具有完全相同的类型Foo
。