Saturday, March 25, 2017

Scala Trait and Mixin - Points to Remember

  • Trait can be viewed not only as interfaces in other languages, but also as classes with only parameterless constructor.
  • Whenever there is some code in trait, the trait is called mixin
  • trait Alarm {
     def trigger(): String
    }
    
  • In scala trait, If we create simple class and pass parameter in constructor, without any val or var, it means, that scope of variable is within constructor only, if we specify val or var, it means, the compile create getter for variables.
  • If one trait have variable and not initialize with some value, then when we mix with some class, we need to declare that variable in primary constructor with val or var or override in scala otherwise we are getting compile time error.
  • error: class V3 needs to be abstract, since value messages 
    in trait V of type String is not defined
    
  • When we create some variable in trait, it defines as abstract method in bytecode because scala have same name space for variables and method.
  • In class perspective, trait have to implement all their methods and have only one constructor that does not accept any parameter.
  • A trait can extend class also (abstract or concrete) .
  • If some trait is mixed with some class during composing like new class with trait , and that trait extends some class like trait extends SomeClass , this means, compiler will expect that the class must be the subclass of SomeClass otherwise we got compile time error.
  • class SomeClass { …. }
     trait xxx extends SomeClass { …. }
     new class with xxx 
    
  • If, two traits have same method signature with different return type and mix with class, compiler gives us error:
  • trait V1 { def hello: String }
     trait V2 {  def hello: Int }
     error: overriding method greeting in trait V1 of type => String;
     method greeting in trait V2 of type => Int has incompatible type
    
  • In scala, If we have two independent traits and have same method signature with implementation and mix by some class. That class, no need to override methods, because traits have its own implementation, that time compiler gives us compile time error.
  • trait Independent1 { def freedom = "Free" }
             trait Independent2 { def freedom = "Free" }
             class Prisoner extends Independent1 with Independent2
    
             Prisoner.scala:9: error: class Prisoner inherits conflicting members:
             method freedom in trait Independent1 of type => String  and
             method freedom in trait Independent2 of type => String
             (Note: this can be resolved by declaring an override in class Prisoner.)
             class Prisoner extends Independent1 with Independent2
    
  • In scala, for solving diamond problem, they are using linearization like which mix last in class, there method is called. Multiple inheritance is only possible using traits.
  •          class E extends B with C // A -> B, A-> C in this case C method will win.
    
  • In linearization calls starts from right to left, and  if traits have same methods and also call super in method body then call will go like hierarchy.
  • trait A2 {  def string = "" }
             trait B2 extends A2 { override def string = "B String" + super.string }
             trait C2 extends B2 { override def string = "C String" + super.string }
             class MultipleMixinM2 extends B2 with C2
             object MultipleMixinM2 extends App 
             { println(new MultipleMixinM2().string) } //C String B String