回答:
Scalaの補助コンストラクターは、最初のアクションとして、(landon9720の)プライマリコンストラクター応答、または同じクラスからの別の補助コンストラクターを呼び出す必要があることを明示的に言及する価値があります。Javaの場合のように、スーパークラスのコンストラクターを明示的または暗黙的に呼び出すことはできません。これにより、プライマリコンストラクターがクラスへの唯一のエントリポイントになります。
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
ケースクラスでもキーワードが必要であることは簡単ではありません。
Scala 2.8.0以降では、コンストラクターとメソッドのパラメーターにデフォルト値を設定することもできます。このような
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)
デフォルト値のあるパラメータは、パラメータリストでデフォルト値のないパラメータの後に来る必要があります。
class Foo(val x:Int, y:Int=2*x)
は動作しません。
new Foo(x=2,z=4)
印刷されますFoo(2,0,4)
。
コードを見ていると、突然、コンストラクターのオーバーロードのようなものがあることに気付きました。それから私はその質問を思い出し、別の答えを出すために戻ってきました:
Scalaでは、コンストラクターをオーバーロードすることはできませんが、関数でこれを行うことができます。
また、apply
コンパニオンオブジェクトの機能をそれぞれのクラスのファクトリにすることを選択する人も少なくありません。
このクラスを抽象化し、このクラスapply
を実装インスタンス化する関数をオーバーロードすると、オーバーロードされた「コンストラクター」ができます。
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)
…
}
}
それぞれapply
を返すように明示的に定義していることに注意してくださいExpectation[T]
。そうしないと、アヒル型のが返されExpectation[T]{val expected: List[T]}
ます。
これを試して
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)
new Foo(z=5)
class Foo(x: Int = 0, y: Int = 0, z: String) {