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?
Respuestas:
Utilice la new
palabra clave cuando desee hacer referencia al class
propio constructor de a:
class Foo { }
val f = new Foo
Omita new
si se refiere al apply
método del objeto complementario :
class Foo { }
object Foo {
def apply() = new Foo
}
// Both of these are legal
val f = Foo()
val f2 = new Foo
Si ha creado una clase de caso:
case class Foo()
Scala crea en secreto un objeto complementario para usted, convirtiéndolo en esto:
class Foo { }
object Foo {
def apply() = new Foo
}
Para que puedas hacer
f = Foo()
Por último, tenga en cuenta que no hay ninguna regla que diga que el apply
método complementario debe ser un proxy del constructor:
class Foo { }
object Foo {
def apply() = 7
}
// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7
Y, como mencionaste las clases de Java: sí, las clases de Java rara vez tienen objetos complementarios con un apply
método, por lo que debes usar new
y el constructor de la clase real.
¿Es cuando intentamos crear instancias de objetos Java solamente?
De ningún modo. Hay dos casos generales en los que omite new
en scala. Con objetos singleton (que a menudo se usan para almacenar funciones estáticas y como una especie de fábrica similar a lo que puede ver en Java):
scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy
scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8
scala> LonelyGuy.mood
res4: java.lang.String = sad
Con clases de caso (en realidad, debajo hay clase + objeto = patrón complementario , por ejemplo, tener clase y objeto con el mismo nombre):
scala> case class Foo(bar: String)
defined class Foo
scala> Foo("baz")
res2: Foo = Foo(baz)
Entonces, cuando trabaja con clases simples, las reglas son las mismas que con Java.
scala> class Foo(val bar: String)
defined class Foo
scala> new Foo("baz")
res0: Foo = Foo@2ad6a0
// will be a error
scala> Foo("baz")
<console>:8: error: not found: value Foo
Foo("baz")
Además, hay clases anónimas en scala, que se pueden construir así:
scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8
scala> res2.bar
res3: java.lang.String = baz
¿Es cuando intentamos crear instancias de objetos Java solamente?
Con Scala 3 (que debería lanzarse a mediados de 2020, ocho años después), basado en Dotty : nunca.
Scala 3 soltará " new
", como en este hilo
Las aplicaciones Creator permiten usar una sintaxis de llamada de función simple para crear instancias de una clase, incluso si no hay un método de aplicación implementado.
Ejemplo:
class StringBuilder(s: String) {
def this() = this(s)
}
StringBuilder("abc") // same as new StringBuilder("abc")
StringBuilder() // same as new StringBuilder()
Las aplicaciones de creador generalizan una funcionalidad proporcionada hasta ahora solo para clases de casos, pero el mecanismo de cómo se logra esto es ligeramente diferente.
En lugar de un método de aplicación generado automáticamente, agregamos una nueva interpretación posible a una llamada de funciónf(args)
.