Wie stellen Sie überladene Konstruktoren in Scala bereit?
Wie stellen Sie überladene Konstruktoren in Scala bereit?
Antworten:
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);
}
new
Schlüsselwort auch für Fallklassen erforderlich ist.
class Foo(x: Int, y: Int) {
def this(x: Int) = this(x, 0) // default y parameter to 0
}
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.
class Foo(val x:Int, y:Int=2*x)
funktioniert nicht.
new Foo(x=2,z=4)
wird gedruckt Foo(2,0,4)
.
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 apply
Funktion 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 apply
für die Rückgabe definiere Expectation[T]
, da es sonst eine Ente zurückgibt Expectation[T]{val expected: List[T]}
.
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
}
}
new Foo(x=2,z=4)
undnew Foo(z=5)
wenn Sie Ihre erste Zeile inclass Foo(x: Int = 0, y: Int = 0, z: String) {