2012-03-15 27 views
70

Ho una domanda molto semplice - quando dovremmo applicare la nuova parola chiave durante la creazione di oggetti in Scala? È quando proviamo a istanziare solo gli oggetti Java?Parola chiave "nuova" in Scala

risposta

112

Utilizzare la parola new quando si vuole fare riferimento a un proprio costruttore di 's class:

class Foo { } 

val f = new Foo 

Omettere new se si fa riferimento al apply metodo dell'oggetto compagna:

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

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

Se Ho realizzato una classe di casi:

case class Foo() 

Scala crea in segreto un oggetto associato per voi, trasformandolo in questo:

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

modo da poter fare

f = Foo() 

Infine, tenere a mente che non c'è una regola che dice che il compagno apply il metodo deve essere un proxy per il costruttore:

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

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

E, dal momento che lei ha citato le classi Java: si - classi Java raramente hav e oggetti associati con un metodo apply, quindi è necessario utilizzare new e il costruttore della classe effettiva.

+0

classe A Java non può mai avere un oggetto associato. Può avere un oggetto che può funzionare come Factory per la classe Java, ma questo oggetto non è il suo oggetto complementare. – sschaef

+0

@Antoras Poiché le classi di Scala compilano in codice bytecode Java e possono essere distribuite in forma compilata, Scala può dire la differenza tra un compagno Scala effettivo e una classe chiamata Foo $ con un membro MODULE $ statico? – Owen

+1

Penso che Scalac possa differire da questo perché si specifica che un oggetto associato debba essere dichiarato nello stesso file della sua classe companion.Poiché la "proprietà" companion esiste solo in Scala e non in livello di codice Bytecode, scalac deve controllare il codice Scala e non il Bytecode per assicurarsi che la specifica sia seguita. – sschaef

13

È quando proviamo a istanziare solo oggetti java?

Niente affatto. Vi sono due casi generali quando si ommit new in scala. Con oggetti Singleton (che vengono oftenly utilizzati per memorizzare funzioni statiche e come una sorta di fabbrica di simile a quello che si può vedere in 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 (in realtà, al di sotto ci sono class + oggetto = companion modello, ad esempio avere classe e oggetto con lo stesso nome):

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


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

Quindi, quando si lavora con un semplice classi, le regole sono le stesse 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") 

bonus, v'è un classi anonime in scala, che possono essere costruiti in questo modo:

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

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