Surcharge du constructeur Scala?


135

Comment fournir des constructeurs surchargés dans Scala?

Réponses:


186

Il convient de mentionner explicitement que les constructeurs auxiliaires de Scala doivent soit appeler la réponse du constructeur principal (comme dans landon9720), soit un autre constructeur auxiliaire de la même classe, comme première action. Ils ne peuvent pas simplement appeler le constructeur de la superclasse explicitement ou implicitement comme ils le peuvent en Java. Cela garantit que le constructeur principal est le seul point d'entrée de la classe.

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: Mauvais exemple? Sans deuxième et troisième constructeurs, l'utilisateur peut toujours appeler new Foo(x=2,z=4)et new Foo(z=5)si vous changez votre première ligne enclass Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828

Les arguments nommés / par défaut n'arrivent pas avant Scala 2.8.
Jon McAuliffe

2
Il serait intéressant de mentionner comment utiliser un constructeur de surcharge. Ce n'est pas anodin que le newmot-clé soit nécessaire même pour les classes de cas.
Readren

33
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }

16

Depuis Scala 2.8.0, vous pouvez également avoir des valeurs par défaut pour les paramètres du constructeur et de la méthode. Comme ça

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)

Les paramètres avec des valeurs par défaut doivent venir après ceux sans valeurs par défaut dans la liste des paramètres.


3
Cela ne fonctionne pas pour les valeurs par défaut non triviales. donc class Foo(val x:Int, y:Int=2*x)ne fonctionne pas.
sous

@ Jörgen Lundberg: vous avez écrit Les paramètres avec des valeurs par défaut doivent venir après ceux sans valeurs par défaut dans la liste des paramètres. C'est faux, new Foo(x=2,z=4)imprimera Foo(2,0,4).
user2987828

@ user2987828 ce que je voulais dire, c'est que vous ne pouvez pas écrire de nouveau Foo (12, x = 2), vous devez écrire un nouveau Foo (x = 2, 12). Vous pouvez écrire un nouveau Foo (12, y = 2), puis vous obtiendrez Foo (12, 2, 0)
Jörgen Lundberg

10

En regardant mon code, je me suis soudainement rendu compte que j'avais une sorte de surcharge d'un constructeur. Je me suis alors souvenu de cette question et suis revenu pour donner une autre réponse:

Dans Scala, vous ne pouvez pas surcharger les constructeurs, mais vous pouvez le faire avec des fonctions.

De plus, beaucoup choisissent de faire de la applyfonction d'un objet compagnon une fabrique pour la classe respective.

En rendant cette classe abstraite et en surchargeant la applyfonction pour implémenter-instancier cette classe, vous avez votre «constructeur» surchargé:

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)}
}

Notez que je définis explicitement chacun applypour retourner Expectation[T], sinon cela renverrait un type de canard Expectation[T]{val expected: List[T]}.


0

Essaye ça

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
  }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.