4

I'm trying to overload the apply method of a case class:

case class Percentage(value: Double)

object Percentage {
  def apply(value: Double): Percentage = {
    if (value < -1) new Percentage(-1.0)
    else if (value > 1) new Percentage(1.0)
    else new Percentage(value)
  }
}

but I get the following error:

method apply is defined twice conflicting symbols both originated in file

Why do I get this error?

Simon
  • 6,025
  • 7
  • 46
  • 98
  • 1
    case classes implicitly add an apply method already.. take a look at this similar question: http://stackoverflow.com/questions/5827510/how-to-override-apply-in-a-case-class-companion – Chris K Apr 12 '17 at 09:23

1 Answers1

8

When you define a case class, the compiler actually generates an apply method. This is the compiled code if you skip defining the apply in the companion object:

$ javap Percentage$.class
Compiled from "SparkHangTest.scala"
public final class org.kp.funspark.Percentage$ implements scala.Serializable {
  public static final org.kp.funspark.Percentage$ MODULE$;
  public static {};
  public org.kp.funspark.Percentage apply(double);
  public scala.Option<java.lang.Object> unapply(org.kp.funspark.Percentage);
}

You're getting the error because you defined the apply with the same parameter and return types as for the generated method. So you're basically trying to override the apply method with an apply that takes the exact same arguments and has the same return type.

If you'd use another argument for apply for example, there are no conflicts:

case class Percentage(value: Double)

object Percentage {
  def apply(value: Int): Percentage = {
    if (value < -1) Percentage(-1.0)
    else if (value > 1) Percentage(1.0)
    else Percentage(value)
  }
}

And the compiled code:

$ javap Percentage$.class
Compiled from "SparkHangTest.scala"
public final class org.kp.funspark.Percentage$ implements scala.Serializable {
  public static final org.kp.funspark.Percentage$ MODULE$;
  public static {};
  public org.kp.funspark.Percentage apply(int); // This is the new apply
  public org.kp.funspark.Percentage apply(double);
  public scala.Option<java.lang.Object> unapply(org.kp.funspark.Percentage);
}
Andrei T.
  • 2,455
  • 1
  • 13
  • 28