Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't I define defaults if I define multiple overloaded constructors in Scala?

I've defined multiple constructors, with some default argument values in all of them. Looks correct (I can't see any ambiguity), but Scala (2.8) compiler complains:

multiple overloaded alternatives of constructor define default arguments

Does it mean that I can't define default values for overloaded constructors at all?

Let me illustrate the situation (primitivized, of course, but illustrative):


class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) {

  def this (subject : Int, factor : Int = 1, doItRight : Boolean = true) = {
    this(subject.toDouble , factor, doItRight)
  }

  def this (subject : String, factor : Int = 1, doItRight : Boolean = true) = {
    this(subject.toDouble , factor, doItRight)
  }

  def this () = {
    this(defaultSubject)
  }

}



like image 775
Ivan Avatar asked Oct 10 '10 08:10

Ivan


2 Answers

Taken straight from the compiler's source code:

// only one overloaded alternative is allowed to define default arguments

In general, I wouldn't advise that you mix overloading and defaults. Even if there's no conflict it can make your code harder to read.

UPDATE

Since you added code, it's clear now that you don't want/need to override the default values for each secondary constructor. In your particular case, I might even question the need for those extra constructors at all; Int=>Double is already available for you as an implicit conversion and String=>Double looks like you might be perverting the type system :)

Also... As an alternative to overloaded constructors, you can define just the primary constructor with defaults, then overload the apply method of the companion object and use that as a factory. This is of course completely optional, but it's rapidly becoming established as a pattern through the use of case classes.

like image 157
Kevin Wright Avatar answered Nov 05 '22 09:11

Kevin Wright


The overloading fails because you (unnessesarily) define multiple constructors with default values. Do this instead:

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) {

  def this (subject : Int) = {
    this(subject.toDouble)
  }

  def this (subject : String) = {
    this(subject.toDouble)
  }

  def this () = {
    this(defaultSubject)
  }
}
like image 37
Mia Clarke Avatar answered Nov 05 '22 11:11

Mia Clarke