Understanding Case class and Traits in Scala

前端 未结 3 581
一生所求
一生所求 2021-02-08 02:53

I have a simple trait as defined below:

trait MyTrait {

  def myStringVal: String

}

My case class which implements this trait is as below:

相关标签:
3条回答
  • 2021-02-08 03:03

    Case classes are different -- some default methods are generated for them. This includes val getters for the parameters. Think of case classes as POJOs -- this is a useful bit of syntactic sugar, since they don't need private members.

    Some other useful methods are generated too, for example copy, toString, apply and unapply.

    0 讨论(0)
  • 2021-02-08 03:16

    Scala case classes have a plenty of boilerplate implemented for you, and having all the constructor parameters automatically exposed as vals is one of these things.

    If you try avoiding vals in a regular class, like that:

    trait MyTrait {
      def myVal: String
    }
    
    class MyClass(myVal: String) extends MyTrait
    

    Compiler will show you the error message, that MyClass has to be abstract, as it does't override myVal method, but adding val or var to the class constructor parameter will solve the issue.

    0 讨论(0)
  • 2021-02-08 03:22

    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?!

    • Convert all constructor parameters to public readonly (val) by default fields
    • Generate the toString(), equals() and hashcode() methods using all constructor params for each method
    • Generate companion object with the same name containing an appropriate apply() 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);
    }   
    
    0 讨论(0)
提交回复
热议问题