Case Class default apply method

17,024

Solution 1

Case classes are implicitly accompanied with a companion object with an apply() that has the same arguments as the primary constructor of the case class.

That is:

case class CasePerson(firstName: String)

Will be accompanied by

object CasePerson{
   def apply(firstName: String) = new CasePerson(firstName)
}

Now if you also explicitly define a companion object, you can think of it as appending to the implicitly defined one.

For instance, in your example you added one new apply to the companion object:

object CasePerson{
   def apply() = new CasePerson("XYZ")
}

This statement, you can think of it as if it is creating an combined companion object:

object CasePerson{
   def apply() = new CasePerson("XYZ") // the one manually added
   def apply(firstName: String) = new CasePerson(firstName) // this one is automatically added
}

Now, if you decide to add your own version of the apply that has the same arguments as the primary constructor, then this will overshadow the default behavior of the case class.

object CasePerson{
   def apply() = new CasePerson("XYZ")
   def apply(s: String) = Seq(new CasePerson(s), new CasePerson(s)) // will replace the default factory for the case class
}

Now, if you call CasePerson("hi") it will instead generate:

List(CasePerson("hi"), CasePerson("hi"))

Solution 2

Scala case classes are syntactic sugar. When you create a case class the Scala compiler will create a companion object with an apply and an unapply method for you, which you can then use as if it simply exists. Here is a link to more in depth information on case classes.

Share:
17,024
ZAHEER AHMED
Author by

ZAHEER AHMED

Updated on July 10, 2022

Comments

  • ZAHEER AHMED
    ZAHEER AHMED almost 2 years

    Assuming we have the following case class:

    case class CasePerson(firstName: String)
    

    And we also define a companion object for it:

    object CasePerson {
     def apply() = new CasePerson( "XYZ" )
    }
    

    Notice that in the example above I explicitly defined a companion object with an apply method, without defining the the default apply method:

    // This "default" apply has the same argument as the primary constructor of the case class
    def apply(firstName : String) = new CasePerson(firstName)
    

    Q: So where does Scala gets this "default" apply? I explicitly defined the companion object here without the default apply and the compiler still knows how to execute this:

    val casePerson = CasePerson("PQR")
    

    How does this work?

  • marios
    marios over 8 years
    My apologies for the down vote, but this is not what the question is asking.
  • Mark
    Mark over 7 years
    Replicating this, the 1st apply works, but the 2nd results in the error message: ambiguous reference to overloaded definition, both method apply in object CasePerson of type (firstName: String)A$A28.this.CasePerson and method apply in object CasePerson of type (s: String)Seq[A$A28.this.CasePerson] match argument types (String)
  • marios
    marios over 7 years
    @Mark thanks for letting me know! Which Scala version did you use?Are you using a REPL? In case you are in a REPL make sure you use the paste: option so both you class and its companion object are defined together in a single block.
  • Yarek T
    Yarek T almost 5 years
    Is there any reason not to use just = CasePerson(...) instead of = new CasePerson(...) in the additional apply methods? (apart from the obvious case where you are overriding the default)