4

My question is that if it is possible to overload constructors in scala?

So I can write code like:

var = new Foo(1)
var = new Foo("bar")

And if it is not possible, are there any equivalent tricks?

missingfaktor
  • 90,905
  • 62
  • 285
  • 365
Zifei Tong
  • 1,697
  • 1
  • 19
  • 32
  • You are talking about constructors, not class initializers. Please change the wording of your question. Class initilizers are run when the class is loaded, while constructors are called when instances of the class are created. – Kim Stebel Sep 25 '10 at 12:09
  • possible duplicate of [Scala constructor overload?](http://stackoverflow.com/questions/1095329/scala-constructor-overload) – Jörg W Mittag Sep 25 '10 at 14:26

3 Answers3

10

Sure, but there are restrictions. Scala requires that one of your constructors be "primary". The primary constructor has the special, convenient syntax of putting the constructor args right after the class name. Other "secondary" constructors may also be defined, but they need to call the primary constructor. This is different than Java, and somewhat more restrictive. It is done this way so that constructor args can be treated as fields.

Your example would look like

class Foo(myArg:String){ //primary constructor
   def this(myIntArg:Int) = this(myIntArg.toString) //secondary constructor
}

val x = new Foo(1)
val y = new Foo("bar")
Dave Griffith
  • 20,435
  • 3
  • 55
  • 76
7

As you can see in Dave Griffith's example, the primary constructor must be the "most general" one in the sense that any other constructor must call it (directly and indirectly). As you can imagine, this leads sometimes to ugly primary constructors. A common strategy is to use the companion object to hide the ugliness (and you don't need to type the "new"):

class Foo private (arg:Either[String, Int]){ 
   ...
}

object Foo {
   def apply(arg:String) = new Foo(Left(arg))
   def apply(arg:Int) = new Foo(Right(arg))  
}

val a = Foo(42)
val b = Foo("answer")

Of course you must be careful if you want to inherit from your class (e.g. this isn't possible in the example above)

Landei
  • 54,104
  • 13
  • 100
  • 195
  • this is better way than auxiliary constructors. because aux constructors can only do some simple fields conversions, but this apply() can do a lot in the code logic to normalize completely different inputs. – linehrr Aug 11 '17 at 07:32
1
class MyCons{    

  def this(msg:String){    
        this()    
        println(msg)   
  }       

  def this(msg1:String , msg2:String){    
        this()    
        println(msg1 +" "+msg2)    
  }    

}   

For other auxiliary constructor we must need to call primary constructor or other auxiliary defined earlier.

  • With questions as old as this one, it's helpful if you explain how your answer differs from the answers already provided. – jwvh Jul 25 '17 at 05:37