Showing posts with label traits. Show all posts
Showing posts with label traits. Show all posts

Saturday, April 29, 2017

Scala Dessign Patterns: Stackable Traits

Introduction

Provide different implementation for a method of a class later. 

Agenda:

Stackable Traits using Scala.

Code:


trait StringWriter {
  def write(str: String): String
}

class BasicWriter extends StringWriter {
  override def write(str: String) = s"Write the following string '${str}'"
}

trait CapitalizingStringLetter extends StringWriter {
  abstract override def write(str: String) = {
    super.write(str.split("\\s+").map(_.capitalize).mkString(" "))
  }
}

trait LowerCaseStringLetter extends StringWriter {
  abstract override def write(str: String) = super.write(str.toLowerCase)
}

trait UpperCaseStringLetter extends StringWriter {
  abstract override def write(str: String) = super.write(str.toUpperCase)
}

object StackableTraits extends App {

  val writer1 = new BasicWriter with UpperCaseStringLetter with CapitalizingStringLetter
  val writer2 = new BasicWriter with CapitalizingStringLetter with LowerCaseStringLetter
  val writer3 = new BasicWriter with UpperCaseStringLetter with LowerCaseStringLetter with CapitalizingStringLetter
  val writer4 = new BasicWriter with LowerCaseStringLetter with CapitalizingStringLetter with UpperCaseStringLetter

  println(s"Writer 1: ${writer1.write("Ticket to Canada .... ")}")
  println(s"Writer 2: ${writer2.write("Ticket to Canada .... ")}")
  println(s"Writer 3: ${writer3.write("Ticket to Canada .... ")}")
  println(s"Writer 4: ${writer4.write("Ticket to Canada .... ")}")
}

Download Code from Github Repo

 

References:

Scala Design Patterns By Ivan Nikolov

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