Überlastung des Scala-Konstruktors?

135

Wie stellen Sie überladene Konstruktoren in Scala bereit?

Landon Kuhn
quelle

Antworten:

186

Es ist ausdrücklich zu erwähnen, dass Hilfskonstruktoren in Scala entweder die Antwort des Primärkonstruktors (wie in landon9720) oder einen anderen Hilfskonstruktor derselben Klasse als erste Aktion aufrufen müssen. Sie können den Konstruktor der Oberklasse nicht einfach explizit oder implizit aufrufen, wie dies in Java möglich ist. Dadurch wird sichergestellt, dass der primäre Konstruktor der einzige Einstiegspunkt in die Klasse ist.

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
quelle
@ Jon McAuliffe: Schlechtes Beispiel? Ohne zweiten und dritten Konstruktor kann der Benutzer weiterhin aufrufen new Foo(x=2,z=4)und new Foo(z=5)wenn Sie Ihre erste Zeile inclass Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828
Named / Default-Argumente kamen erst in Scala 2.8 an.
Jon McAuliffe
2
Es wäre erwähnenswert, wie ein Überlastungskonstruktor verwendet wird. Es ist nicht trivial, dass das newSchlüsselwort auch für Fallklassen erforderlich ist.
Readren
33
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }
Landon Kuhn
quelle
16

Ab Scala 2.8.0 können Sie auch Standardwerte für Konstruktor- und Methodenparameter festlegen. So was

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)

Parameter mit Standardwerten müssen nach denen ohne Standardwerte in der Parameterliste stehen.

Jörgen Lundberg
quelle
3
Dies funktioniert jedoch nicht für nicht triviale Standardeinstellungen. so class Foo(val x:Int, y:Int=2*x)funktioniert nicht.
Subsub
@ Jörgen Lundberg: Sie haben Parameter mit Standardwerten geschrieben, die nach denen ohne Standardwerte in der Parameterliste kommen müssen. Es ist falsch, new Foo(x=2,z=4)wird gedruckt Foo(2,0,4).
user2987828
@ user2987828 Ich meinte, du kannst kein neues Foo schreiben (12, x = 2), du musst neues Foo schreiben (x = 2, 12). Sie können neue Foo (12, y = 2) schreiben, dann erhalten Sie Foo (12, 2, 0)
Jörgen Lundberg
10

Beim Betrachten meines Codes wurde mir plötzlich klar, dass ich einen Konstruktor irgendwie überladen habe. Ich erinnerte mich dann an diese Frage und kam zurück, um eine andere Antwort zu geben:

In Scala können Sie Konstruktoren nicht überladen, aber Sie können dies mit Funktionen tun.

Auch viele entscheiden sich dafür, das zu machen apply Funktion eines Begleitobjekts zu einer Fabrik für die jeweilige Klasse zu machen.

Wenn Sie diese Klasse abstrakt machen und die applyFunktion zum Implementieren und Instanziieren dieser Klasse überladen, haben Sie Ihren überladenen „Konstruktor“:

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

Beachten Sie, dass ich jedes explizit applyfür die Rückgabe definiere Expectation[T], da es sonst eine Ente zurückgibt Expectation[T]{val expected: List[T]}.

fliegende Schafe
quelle
0

Versuche dies

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
quelle