I have a simple trait as defined below:
trait MyTrait {
def myStringVal: String
}
My case class which implements this trait is as below:
case class MyCaseClass(myStringVal: String) extends MyTrait {
...
...
}
Coming from a Java world, I find it a bit difficult to fathom the fact that MyCaseClass actually implements this just by defining a parameter to MyCaseClass. I understand that thy byte code would actually write the getter and setter. But how is this possible without any var or val?
My understanding is that if there is no var or val, then there is no getter or setter method generated. In that case how is the above case class MyCaseClass implementing myStringVal method?
Sometime too much of this Scala magic is difficult to understand especially with legacy code.
You might want to check out this blog article covering what case classes exactly are and why they are so useful.
In your example, the trait MyTrait
has no use, except being able to function like a java interface. Note, that the default visibility in scala is public. By default case class parameters are immutable so in your example val
is automatically inferred by the compiler for the myStringVal
argument.
What magic do case classes do?!
val
) by default fieldstoString()
, equals()
and hashcode()
methods using all constructor params for each methodapply()
and unapply()
method, which are basically just a convenience constructor allowing to instantiate without using the new
keyword and an extractor which by default generates an option-wrapped tuple
of the case class parameters.EDIT: Sample compiler output for (case) classes (copied from scalatutorial.de)
A simple scala class definition like
class A1(v1: Int, v2: Double)
gets compiled to the java code
public class A1 extends java.lang.Object implements scala.ScalaObject {
public A1(int, double);
}
the analogous case class
case class A2(v1: Int, v2: Double)
gets compiled to the following java classes
public class A2 extends java.lang.Object implements
scala.ScalaObject,scala.Product,java.io.Serializable {
public static final scala.Function1 tupled();
public static final scala.Function1 curry();
public static final scala.Function1 curried();
public scala.collection.Iterator productIterator();
public scala.collection.Iterator productElements();
public double copy$default$2();
public int copy$default$1();
public int v1();
public double v2();
public A2 copy(int, double);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public boolean canEqual(java.lang.Object);
public A2(int, double);
}
public final class A2$ extends scala.runtime.AbstractFunction2
implements scala.ScalaObject {
public static final A2$ MODULE$;
public static {};
public scala.Option unapply(A2);
public A2 apply(int, double);
public java.lang.Object apply(java.lang.Object, java.lang.Object);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With