Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case Class default apply method

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?

like image 233
ZAHEER AHMED Avatar asked Dec 30 '15 16:12

ZAHEER AHMED


People also ask

Can case class have methods?

case classes automatically have equality and nice toString methods based on the constructor arguments. case classes can have methods just like normal classes.

What methods get generated when we declare a case class?

equals and hashCode methods are generated, which let you compare objects and easily use them as keys in maps.

How do you add methods to a case class?

Adding method to a case class is mostly the same as adding method to non-case class. So you can write: case class MyCaseClass(cParam1: Int, cParam2: String) { def myFunc: Sting = ??? }

Can we use CASE classes in pattern matching?

Case classes help us use the power of inheritance to perform pattern matching. The case classes extend a common abstract class. The match expression then evaluates a reference of the abstract class against each pattern expressed by each case class.


2 Answers

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"))
like image 120
marios Avatar answered Sep 18 '22 07:09

marios


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.

like image 29
Lodewijk Bogaards Avatar answered Sep 20 '22 07:09

Lodewijk Bogaards