Scala Quick Notes :: Part - 4


Bhaskar S 01/24/2015


Overview

In this part of the series, we will continue to look at the Object-Oriented capabilities of Scala such as Inheritence, Polymorphism, Abstract Class and Case Class.

Hands-on With Scala - IV

The following is the Scala program named Sample12.scala:

Sample12.scala
/*
 *
 * Name  : Sample12
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/24/2015
 *  
 */

package com.polarsparc.scala

class Vehicle(val name: String) {
  override def toString() = {
    "Vehicle-[" + name + ">]"
  }
}

class LandVehicle(name: String, val wheels: Int = 2) extends Vehicle(name) {
  override def toString() = {
    "LandVehicle-[" + name + " <" + wheels + ">]"
  }
}

class Bike(val make: String) extends LandVehicle ("Bike") {
  override def toString() = {
    "Bike-[" + name + " <" + wheels + ">, " + make + "]"
  }
}

class Car(val make: String, val year: Int) extends LandVehicle ("Car", 4) {
  override def toString() = {
    "Car-[" + name + " <" + wheels + ">, " + make + ", " + year + "]"
  }
}

object Sample12 {
  def main(args: Array[String]) = {
    printf("[1] Class name = %s\n", classOf[LandVehicle])
    printf("[2] Class name = %s\n", classOf[Bike])
    printf("[3] Class name = %s\n", classOf[Car])
    
    val v1 = new Vehicle("Unknown")
    printf("v1 = %s\n", v1)
    
    printf("v1 Class name = %s\n", v1.getClass)
    
    val v2: Vehicle = new Bike("BMW")
    printf("v2 = %s, name = %s\n", v2, v2.name)
    
    printf("v2 is a type of LandVehicle ? %s\n", v2.isInstanceOf[LandVehicle])
    
    printf("v2 Class name = %s\n", v2.getClass)
    
    val v3 = new Car("Tesla", 2015)
    printf("v3 = %s, make = %s, year = %d\n", v3, v3.make, v3.year)
    
    printf("v3 Class name = %s\n", v3.getClass)
    
    val v4 = v3.asInstanceOf[LandVehicle]
    printf("v4 wheels = %d\n", v4.wheels)
    // printf("v4 year = %d\n", v4.year) - This will cause a compiler error if uncommented
  }
}

Executing the program Sample12.scala results in the output:

Output (Sample12.scala)

[1] Class name = class com.polarsparc.scala.LandVehicle
[2] Class name = class com.polarsparc.scala.Bike
[3] Class name = class com.polarsparc.scala.Car
v1 = Vehicle-[Unknown>]
v1 Class name = class com.polarsparc.scala.Vehicle
v2 = Bike-[Bike <2>, BMW], name = Bike
v2 is a type of LandVehicle ? true
v2 Class name = class com.polarsparc.scala.Bike
v3 = Car-[Car <4>, Tesla, 2015], make = Tesla, year = 2015
v3 Class name = class com.polarsparc.scala.Car
v4 wheels = 4

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

The following is the Scala program named Sample13.scala:

Sample13.scala
/*
 *
 * Name  : Sample13
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/24/2015
 *  
 */

package com.polarsparc.scala

abstract class Trigger(val name: String) {
  val desc: String
  
  def action: String
  
  def message = {
    printf("Hello " + name + "!!!\n")
  }
}

class VisualTrigger(name: String, val lumens: Int) extends Trigger(name) {
  val desc = "Alert"
    
  override def action = " ***FLASH*** "
  
  override def toString() = {
    "VisualTrigger-[" + desc + ": " + name + this.action + lumens + " lm>]"
  }
}

class SoundTrigger(name: String, val decibels: Int) extends Trigger(name) {
  val desc = "Alarm"
    
  override def action = " ***SCREECH*** "
  
  override def toString() = {
    "SoundTrigger-[" + desc + ": " + name + this.action + decibels + " db>]"
  }
}

object Sample13 {
  def main(args: Array[String]) = {
    val t1: Trigger = new VisualTrigger("Happy", 800)
    printf("t1 = %s\n", t1)
    t1.message
    
    val t2: Trigger = new SoundTrigger("Panic", 100)
    printf("t2 = %s\n", t2)
    t2.message
  }
}

Executing the program Sample13.scala results in the output:

Output (Sample13.scala)

t1 = VisualTrigger-[Alert: Happy ***FLASH*** 800 lm>]
Hello Happy!!!
t2 = SoundTrigger-[Alarm: Panic ***SCREECH*** 100 db>]
Hello Panic!!!

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

The following is the Scala program named Sample14.scala:

Sample14.scala
/*
 *
 * Name  : Sample14
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/24/2015
 *  
 */

package com.polarsparc.scala

class Snack private (name: String) {
  override def toString() = {
    "Snack-[" + name + "]"
  }
}

object Snack {
  def apply(name: String) = {
    new Snack(name)
  }
}

object Sample14 {
  def main(args: Array[String]) = {
    val s1 = Snack("Bagel")
    printf("s1 = %s\n", s1)
    val s2 = Snack("Waffle")
    printf("s2 = %s\n", s2)
  }
}

Executing the program Sample14.scala results in the output:

Output (Sample14.scala)

s1 = Snack-[Bagel]
s2 = Snack-[Waffle]

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

Notice that we did not use the new keyword when creating an instance of Snack. This is because we have implemented the apply method on the companion object which acts like a factory method for creating class instances.

The following is the Scala program named Sample15.scala:

Sample15.scala
/*
 *
 * Name  : Sample15
 * 
 * Author: Bhaskar S
 *  
 * Date  : 01/24/2015
 *  
 */

package com.polarsparc.scala

class Contact1(val name: String, val email: String)

case class Contact2(name: String, email: String)

object Sample15 {
  def main(args: Array[String]) = {
    val c1 = new Contact1("Alice", "alice@earth.com")
    val c11 = new Contact1("Alice", "alice@earth.com")
    printf("c1 = %s\n", c1)
    printf("c1.hashCode = %d\n", c1.hashCode)
    printf("c1.equals(c11) = %s\n", c1.equals(c11))
    
    val c2 = new Contact2("Alice", "alice@earth.com")
    val c22 = new Contact2("Alice", "alice@earth.com")
    printf("c2 = %s\n", c2)
    printf("c2.hashCode = %d\n", c2.hashCode)
    printf("c2.equals(c22) = %s\n", c2.equals(c22))
    
    val c3 = Contact2("Bob", "bob@space.com")
    val c33 = Contact2("Bob", "bob@space.com")
    printf("c3 = %s\n", c3)
    printf("c3.hashCode = %d\n", c3.hashCode)
    printf("c3.equals(c33) = %s\n", c3.equals(c33))
    
    c2 match {
      case Contact2(n, e) => printf("Name: %s, Email: %s\n", n, e)
    }
  }
}

Executing the program Sample15.scala results in the output:

Output (Sample15.scala)

c1 = com.polarsparc.scala.Contact1@5cad8086
c1.hashCode = 1554874502
c1.equals(c11) = false
c2 = Contact2(Alice,alice@earth.com)
c2.hashCode = -106199946
c2.equals(c22) = true
c3 = Contact2(Bob,bob@space.com)
c3.hashCode = -521222824
c3.equals(c33) = true
Name: Alice, Email: alice@earth.com

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

References

Scala Quick Notes :: Part - 1

Scala Quick Notes :: Part - 2

Scala Quick Notes :: Part - 3