112

In Scala 2.8 is there a way to overload constructors of a case class?

If yes, please put a snippet to explain, if not, please explain why?

Felix
  • 8,385
  • 10
  • 40
  • 59

2 Answers2

204

Overloading constructors isn't special for case classes:

case class Foo(bar: Int, baz: Int) {
  def this(bar: Int) = this(bar, 0)
}

new Foo(1, 2)
new Foo(1)

However, you may like to also overload the apply method in the companion object, which is called when you omit new.

object Foo {
  def apply(bar: Int) = new Foo(bar)
}

Foo(1, 2)
Foo(1)

In Scala 2.8, named and default parameters can often be used instead of overloading.

case class Baz(bar: Int, baz: Int = 0)
new Baz(1)
Baz(1)
retronym
  • 54,768
  • 12
  • 155
  • 168
  • Very nice :) I was looking for something like fallback values in scala, is it new from 2.8 ? I didn't know :) – Felix Mar 10 '10 at 14:23
  • Yes, Named and Default parameters are new in Scala 2.8. – retronym Mar 10 '10 at 22:17
  • 11
    Martin Odersky explains why the additional apply methods aren't added automatically: http://www.scala-lang.org/node/976 – Seth Tisue Apr 15 '10 at 12:56
  • 2
    And how i can use local variables inside overloaded constructor? For example: `def this(bar: Int) = { val test = 0; this(bar,test) }` (this is doesn't work) – HEX Oct 15 '13 at 14:52
  • secondary constructors – retronym Oct 27 '13 at 11:43
  • It seems that if your secondary constructor takes another instance of Foo, you must use the ```apply``` method above with the companion object. Otherwise you get an error trying to use the secondary constructor that indicates the compiler expects the primary. – pferrel May 16 '14 at 16:58
  • @HEX When defining a secondary constructor on a case class, you must immediately invoke this(...); you're prevented from doing any parsing/validating of the passed parameters. If you want/need to parse/validate, you must create an explicit companion object and introduce an appropriate apply method (same signature as your desired function). What I have found over time is to stay away from case class secondary constructors. It is way preferable to stick with adding apply methods to the companion object. Please see my related answer on another thread: http://stackoverflow.com/a/25538287/501113 – chaotic3quilibrium Aug 27 '14 at 23:53
24

You can define an overloaded constructor the usual way, but to invoke it you have to use the "new" keyword.

scala> case class A(i: Int) { def this(s: String) = this(s.toInt) }
defined class A

scala> A(1)
res0: A = A(1)

scala> A("2")
<console>:8: error: type mismatch;
 found   : java.lang.String("2")
 required: Int
       A("2")
         ^

scala> new A("2")
res2: A = A(2)
nbro
  • 15,395
  • 32
  • 113
  • 196
Lukas Rytz
  • 1,894
  • 14
  • 27