斯卡拉 - 新VS对象扩展(Scala - new vs object extends)

2019-08-31 23:39发布

什么是使用new运算符VS通过扩展类中定义一个独立的对象定义对象之间的区别?

更具体地讲,是给定类型class GenericType { ... }之间的区别是什么val a = new GenericTypeobject a extends GenericType

Answer 1:

作为一个实际问题, object声明初始化相同的机制作为new的字节码。 但是,也有相当多的不同之处:

  • object作为单身-每个属于其中只有一个实例存在的类;
  • object被延迟初始化-它们将只创建/初始化时首先提到;
  • 一个object和一个class (或trait的同名)是同伴 ;
  • 上定义的方法object产生的伴侣静态代理class ;
  • 该成员object可以访问同伴的私有成员class ;
  • 对于implicits搜索时,相关的*类或性状的同伴对象看着。

这些只是一些我能想到蝙蝠的权利的差异。 有可能是别人。

*什么是“相关”类或性状是一个较长的故事 - 查找解释它,如果你有兴趣的堆栈溢出的问题。 看看wiki上scala的标签,如果你很难找到他们。



Answer 2:

对象定义(无论扩展的东西与否)是指单对象的创建。

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


Answer 3:

虽然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)

因此,尽管之间的语义差异objectlazy val (在特定的特殊处理object由该语言的,如所概述的丹尼尔C.索布拉尔),一个lazy val总是可以与相应的取代的object (未,它是一个非常好的做法),和同样的lazy val / object是一类/特质的成员。 我能想到的主要实际差异将对象具有一个更具体的静态类型: b是类型的b.type (其延伸Foo ),而a具有完全相同的类型Foo



文章来源: Scala - new vs object extends
标签: scala