Scala Quick Notes :: Part - 5


Bhaskar S 01/31/2015


Overview

In this part of the series, we will continue to look at the Object-Oriented capabilities of Scala such as Traits and Operator Overloading.

Hands-on With Scala - V

The following is the Scala program named Sample16.scala:

Sample16.scala
/*
 *
 * Name  : Sample16
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/31/2015
 *  
 */

package com.polarsparc.scala

trait Person {
  val name: String
  
  var age: Int
  
  val state: String = "NY"
  
  def show = println(s"My name is ${name} of ${age} and resident of ${state}")
}

trait Electrician {
  def wire = println("I am an electrician")
}

trait Plumber {
  def plumb = println("I am a plumber")
}

class NoPro(val n: String, val a: Int) extends Person {
  override val name = n
  var age = a
}

class EPPro(val n: String, val a: Int) extends Person with Electrician with Plumber {
  override val name = n
  var age = a
  
  override def show = println(s"My name is ${name} of ${age}, a resident of ${state} and an Electrician & Plumber")
}

object Sample16 {
  def main(args: Array[String]) = {
    val a = new NoPro("Alice", 30)
    a.show
    
    val b = new EPPro("Bob", 45)
    b.show
    b.wire
    b.plumb
  }
}

Executing the program Sample16.scala results in the output:

Output (Sample16.scala)

My name is Alice of 30 and resident of NY
My name is Bob of 45, a resident of NY and an Electrician & Plumber
I am an electrician
I am a plumber

The following section explains some of the aspects of the Scala program Sample16.scala:

The following is the Scala program named Sample17.scala:

Sample17.scala
/*
 *
 * Name  : Sample17
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/31/2015
 *  
 */

package com.polarsparc.scala

import java.util.Calendar
import java.text.SimpleDateFormat

abstract class Logger {
  def log(msg: String): Unit
}

class SimpleLogger extends Logger {
  def log(msg: String): Unit = println(msg)
}

trait DatedLogger extends Logger {
  val dfmt = new SimpleDateFormat("MM/dd/yyyy")
  
  abstract override def log(msg: String): Unit = {
    val now = Calendar.getInstance().getTime()
    
    super.log("[" + dfmt.format(now) + "] " +msg)
  }
}

trait TimedLogger extends Logger {
  val tfmt = new SimpleDateFormat("HH:mm:ss")
  
  abstract override def log(msg: String): Unit = {
    val now = Calendar.getInstance().getTime()
    
    super.log("[" + tfmt.format(now) + "] " +msg)
  }
}

class DecoratedOneSimpleLogger extends SimpleLogger with DatedLogger
class DecoratedTwoSimpleLogger extends SimpleLogger with TimedLogger
class DecoratedThreeSimpleLogger extends SimpleLogger with DatedLogger with TimedLogger

object Sample17 {
  def main(args: Array[String]) = {
    val sl1 = new SimpleLogger
    sl1.log("This is from SimpleLogger")
    
    val sl2 = new DecoratedOneSimpleLogger
    sl2.log("This is from DecoratedOneSimpleLogger")
    
    val sl3 = new DecoratedTwoSimpleLogger
    sl3.log("This is from DecoratedTwoSimpleLogger")
    
    val sl4 = new DecoratedThreeSimpleLogger
    sl4.log("This is from DecoratedThreeSimpleLogger")
  }
}

Executing the program Sample17.scala results in the output:

Output (Sample17.scala)

This is from SimpleLogger
[02/01/2015] This is from DecoratedOneSimpleLogger
[19:58:10] This is from DecoratedTwoSimpleLogger
[02/01/2015] [19:58:10] This is from DecoratedThreeSimpleLogger

The following section explains some of the aspects of the Scala program Sample17.scala:

The following is the Scala program named Sample18.scala:

Sample18.scala
/*
 *
 * Name  : Sample18
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/31/2015
 *  
 */

package com.polarsparc.scala

class Fraction(val num: Int, val den: Int) {
  private def modDen(other: Fraction) = den * other.den
  
  def + (other: Fraction): Fraction = {
    val mnum = num * other.den + den * other.num
    new Fraction(mnum, modDen(other))
  }
  
  def - (other: Fraction): Fraction = {
    val mnum = num * other.den - den * other.num
    new Fraction(mnum, modDen(other))
  }
  
  def * (other: Fraction): Fraction = new Fraction(num * other.num, modDen(other))
    
  override def toString = num + "/" + den
}

object Sample18 {
  def main(args: Array[String]) = {
    val f1 = new Fraction(1, 2)
    
    printf("f1 = %s\n", f1)
    
    val f2 = new Fraction(2, 3)
    
    printf("f2 = %s\n", f2)
    
    printf("f1 + f2 = %s\n", f1 + f2)
    
    printf("f1 - f2 = %s\n", f1 - f2)
    
    printf("f1 * f2 = %s\n", f1 * f2)
  }
}

Executing the program Sample18.scala results in the output:

Output (Sample18.scala)

f1 = 1/2
f2 = 2/3
f1 + f2 = 7/6
f1 - f2 = -1/6
f1 * f2 = 2/6

The following section explains one of the aspects of the Scala program Sample18.scala:

In Scala, operators are actually just another syntax for ordinary method calls. In other words, the expression o1 + o2 is in actuality the same as (o1).+(o2).

In our example for the Fraction class, we have defined three operator methods - one for addition (+), one for subtraction (-) and one for multiplication (*).

References

Scala Quick Notes :: Part - 1

Scala Quick Notes :: Part - 2

Scala Quick Notes :: Part - 3

Scala Quick Notes :: Part - 4