¿Sobrecarga del constructor Scala?

135

¿Cómo se proporcionan constructores sobrecargados en Scala?

Landon Kuhn
fuente

Respuestas:

186

Vale la pena mencionar explícitamente que los Constructores auxiliares en Scala deben llamar a la respuesta del constructor primario (como en landon9720) u otro constructor auxiliar de la misma clase, como su primera acción. No pueden simplemente llamar explícita o implícitamente al constructor de la superclase como pueden hacerlo en Java. Esto asegura que el constructor primario es el único punto de entrada a la clase.

class Foo(x: Int, y: Int, z: String) {  
  // default y parameter to 0  
  def this(x: Int, z: String) = this(x, 0, z)   
  // default x & y parameters to 0
  // calls previous auxiliary constructor which calls the primary constructor  
  def this(z: String) = this(0, z);   
}
Jon McAuliffe
fuente
@ Jon McAuliffe: ¿mal ejemplo? Sin el segundo y el tercer constructor, el usuario aún puede llamar new Foo(x=2,z=4)y new Foo(z=5)si cambia su primera línea aclass Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828
Los argumentos con nombre / predeterminados no llegaron hasta Scala 2.8.
Jon McAuliffe
2
Vale la pena mencionar cómo utilizar un constructor de sobrecarga. No es trivial que la newpalabra clave sea necesaria incluso para las clases de casos.
Readren
33
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }
Landon Kuhn
fuente
16

A partir de Scala 2.8.0, también puede tener valores predeterminados para los parámetros de contructor y método. Me gusta esto

scala> class Foo(x:Int, y:Int = 0, z:Int=0) {                           
     | override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
     | }
defined class Foo

scala> new Foo(1, 2, 3)                                                    
res0: Foo = Foo(1, 2, 3)

scala> new Foo(4)                                                          
res1: Foo = Foo(4, 0, 0)

Los parámetros con valores predeterminados deben aparecer después de los que no tienen valores predeterminados en la lista de parámetros.

Jörgen Lundberg
fuente
3
Sin embargo, esto no funciona para los valores predeterminados no triviales. por lo que class Foo(val x:Int, y:Int=2*x)no funciona.
subsub
@ Jörgen Lundberg: usted escribió Los parámetros con valores predeterminados deben ir después de los que no tienen valores predeterminados en la lista de parámetros. Está mal, new Foo(x=2,z=4)se imprimirá Foo(2,0,4).
user2987828
@ user2987828 lo que quise decir es que no puedes escribir Foo nuevo (12, x = 2) debes escribir Foo nuevo (x = 2, 12). Puede escribir un nuevo Foo (12, y = 2), luego obtendrá Foo (12, 2, 0)
Jörgen Lundberg
10

Mientras miraba mi código, de repente me di cuenta de que sobrecargaba un constructor. Entonces recordé esa pregunta y regresé para dar otra respuesta:

En Scala, no puede sobrecargar los constructores, pero puede hacerlo con funciones.

Además, muchos optan por hacer que la applyfunción de un objeto complementario sea una fábrica para la clase respectiva.

Haciendo que esta clase sea abstracta y sobrecargando la applyfunción para implementar-instanciar esta clase, tiene su "constructor" sobrecargado:

abstract class Expectation[T] extends BooleanStatement {
    val expected: Seq[T]}

object Expectation {
    def apply[T](expd:     T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
    def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected =      expd }

    def main(args: Array[String]): Unit = {
        val expectTrueness = Expectation(true)}
}

Tenga en cuenta que defino explícitamente cada uno applypara devolver Expectation[T], de lo contrario, devolvería un tipo de pato Expectation[T]{val expected: List[T]}.

ovejas voladoras
fuente
0

Prueba esto

class A(x: Int, y: Int) {
  def this(x: Int) = this(x, x)
  def this() = this(1)
  override def toString() = "x=" + x + " y=" + y
  class B(a: Int, b: Int, c: String) {
    def this(str: String) = this(x, y, str)
    override def toString() =
      "x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
  }
}
anish
fuente