class MyClass(constructorParam:Any)
. Unlike Java, that constructor must be called. The question that often arises is, "How can one define multiple constructors?" There is a simple way to do this, however often a factory companion object can be used to remove the need for multiple constructors. Factory Companion Objects are covered in a previous post but I will review the pattern here quickly.First multiple constructors:
- scala> class HelloConstructor(param1:Int, param2:Int) {
- | def this(onlyParam:Int) = this(onlyParam,onlyParam)
- | def this(p1:String, p2:String, p3:String) = this(p1.length, p2.length + p3.length)
- | def this(onlyParam:String) = this(onlyParam.length)
- | }
- defined class HelloConstructor
In Java if a constructor calls another constructor that call must be the first statement in the constructor. Scala is the same except that in Scala the primary constructor must be called. Notice that all constructors call this(param1,param2) at some point. In addition any method defined in the class HelloConstructor is not available until after the primary constructor is invoked. The following examples are not valid.
- scala> class HelloConstructor(param1:Int, param2:Int) {
- | def x = 1
- | def this() = this(x,3)
- | }
- <console>:6: error: not found: value x
- def this() = this(x,3)
- scala> class HelloConstructor(param1:Int, param2:Int) {
- | def this() = {
- | println("constructing") // the REPL won't even let me finish method definition
- <console>:3: error: 'this' expected but identifier found.
- println("constructing")
- ^
Factory companion objects can be used to work around these restrictions:
- scala> class HelloConstructor(param1:Int, param2:Int)
- defined class HelloConstructor
- scala> object HelloConstructor {
- | def apply() = {
- | println("constructing object")
- | new HelloConstructor(1,2)
- | }
- | }
- defined module HelloConstructor
- scala> HelloConstructor()
- constructing object
- res1: HelloConstructor = HelloConstructor@5b0010ec
Since companion objects can access private members of the class the factory methods can be as powerful as a constructor without the restrictions.
One last idea that is useful when designing classes is Scala 2.8 default arguments:
- scala> class HelloConstructor(param1: Int = 1, param2: Int = 2)
- defined class HelloConstructor
- scala> new HelloConstructor()
- res0: HelloConstructor = HelloConstructor@7cd47880
- scala> new HelloConstructor(1)
- res1: HelloConstructor = HelloConstructor@3834a1c8
- scala> new HelloConstructor(param1 = 1)
- res2: HelloConstructor = HelloConstructor@3b3e3940
- scala> new HelloConstructor(param2 = 1)
- res3: HelloConstructor = HelloConstructor@6dee2ea8
- scala> new HelloConstructor(3,4)
- res4: HelloConstructor = HelloConstructor@397b6074
- scala> new HelloConstructor(param1 = 3, param2=4)
- res5: HelloConstructor = HelloConstructor@20272fec
No comments:
Post a Comment