Scalaコンストラクターのオーバーロード?


135

Scalaではオーバーロードされたコンストラクターをどのように提供しますか?

回答:


186

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

@ジョン・マコーリフ:悪い例?2番目と3番目のコンストラクターがなくても、ユーザーは引き続き呼び出すことができ、最初の行をnew Foo(x=2,z=4)new Foo(z=5)class Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828

名前付き/デフォルトの引数はScala 2.8まで届きませんでした。
Jon McAuliffe 2014

2
オーバーロードコンストラクターの使用方法について言及する価値があります。newケースクラスでもキーワードが必要であることは簡単ではありません。
Readren


16

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)

デフォルト値のあるパラメータは、パラメータリストでデフォルト値のないパラメータの後に来る必要があります。


3
ただし、これは重要なデフォルトでは機能しません。これclass Foo(val x:Int, y:Int=2*x)は動作しません。
subsub

@JörgenLundberg:デフォルト値のあるパラメーターを記述した場合、パラメーターリストでデフォルト値のないパラメーターの後に配置する必要があります。間違っています、new Foo(x=2,z=4)印刷されますFoo(2,0,4)
user2987828 2014

@ user2987828私が意味したことは、あなたが新しいFoo(12、x = 2)を書くことができないということです。あなたは新しいFoo(x = 2、12)を書かなければなりません。あなたは、あなたがfoo(12、2、0)を取得します新しいフー(12、Y = 2)を書くことができます
ヨルゲンLundbergの

10

コードを見ていると、突然、コンストラクターのオーバーロードのようなものがあることに気付きました。それから私はその質問を思い出し、別の答えを出すために戻ってきました:

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]}ます。


0

これを試して

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
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.