2012-03-15 18 views
70

Tengo una pregunta muy simple: ¿cuándo deberíamos aplicar la nueva palabra clave al crear objetos en Scala? ¿Es cuando intentamos crear instancias de objetos Java solamente?palabra clave "nueva" en Scala

Respuesta

112

utilizar la palabra clave new cuando se quiere hacer referencia a una propia constructora class 's:

class Foo { } 

val f = new Foo 

Omitir new si se está refiriendo a apply el método del objeto compañera:

class Foo { } 
object Foo { 
    def apply() = new Foo 
} 

// Both of these are legal 
val f = Foo() 
val f2 = new Foo 

Si He hecho una clase de caso:

case class Foo() 

Scala en secreto crea un objeto compañero para usted, convirtiéndolo en esto:

class Foo { } 
object Foo { 
    def apply() = new Foo 
} 

para que pueda hacer

f = Foo() 

Por último, tenga en cuenta que no hay ninguna regla que dice que el compañero apply método tiene que ser un proxy para el constructor:

class Foo { } 
object Foo { 
    def apply() = 7 
} 

// These do different things 
> println(new Foo) 
[email protected] 
> println(Foo()) 
7 

Y, ya que ha mencionado clases Java: Sí - clases Java raramente por pla e objetos complementarios con un método apply, por lo que debe usar new y el constructor de la clase real .

+0

clase de Java nunca puede tener un objeto acompañante. Puede tener un objeto que pueda funcionar como una Factory para la clase Java, pero este objeto no es su objeto complementario. – sschaef

+0

@Antoras Dado que las clases de Scala se compilan en bytecode de Java y se pueden distribuir de forma compilada, ¿Scala puede diferenciar entre un compañero real de Scala y una clase llamada Foo $ con un miembro de MODULE $ estático? – Owen

+1

Creo que Scalac puede diferir porque se especifica que un objeto complementario debe declararse en el mismo archivo que su clase complementaria.Debido a que la "propiedad" acompañante sólo existe en Scala y no en scalac a nivel de código de bytes tiene que comprobar el código Scala y no el código de bytes para asegurarse de que se sigue la especificación. – sschaef

13

¿Es cuando intentamos instanciar solo objetos java?

No, en absoluto. Hay dos casos generales cuando omite new en scala. con objetos simples (que se utilizan oftenly para almacenar funciones estáticas y como una especie de fábrica similar a lo que puede verse en java):

scala> object LonelyGuy { def mood = "sad" } 
defined module LonelyGuy 

scala> LonelyGuy 
res0: LonelyGuy.type = [email protected] 

scala> LonelyGuy.mood 
res4: java.lang.String = sad 

Con un case classes (en realidad, debajo hay son de clase + objeto = companion patrón, por ejemplo, con clase y objeto con el mismo nombre):

scala> case class Foo(bar: String) 
defined class Foo 


scala> Foo("baz") 
res2: Foo = Foo(baz) 

Así que cuando se trabaja con unas simples clases, las reglas son las mismas que con Java.

scala> class Foo(val bar: String) 
defined class Foo 

scala> new Foo("baz") 
res0: Foo = [email protected] 

// will be a error 
scala> Foo("baz") 
<console>:8: error: not found: value Foo 
     Foo("baz") 

Bono, hay una clases anónimas en Scala, que pueden ser construidas de esta manera:

scala> new { val bar = "baz" } 
res2: java.lang.Object{val bar: java.lang.String} = [email protected] 

scala> res2.bar 
res3: java.lang.String = baz 
Cuestiones relacionadas