Functional Objects and Methods

The journey of exploring scala language continues. In our previous post we discussed about the class and object. In this post we will look into closer use of objects and methods in scala. To understand the theory lets try to implement a simple calculator using scala.

The Scala compiler will compile any code you place in the class body, which isn’t part of a field or a method definition, into the primary constructor.

class Calculator(n: Int, d: Int){
  //debug message
  println(s"cal values: $n and $d")
}
image
Figure 1 - Scala Constructor

Reimplementing the toString method

By default, scala class inherits the implementation of “toString” defined in class java.lang.Object, which just prints the class name, an @ sign, and a hexadecimal number (Figure 1 - Calculator@57257f14). We can override the default implementation by adding a method toString to our class.

class Calculator(n: Int, d: Int){
  //override toString
  override def toString = s"cal values: $n and $d"
}
image
Figure 2 - toString Override

In a calculator program mostly a known error, when a value is dividing by zero. So we need to handle this problem. The best approach is to define as a precondition of the primary constructor stage. One way to do that is to use scala “require” function.

Require method takes one boolean parameter. If the condition is true it will return true or stop the execution by throwing an IllegalArgumentException

class Calculator(n: Int, d: Int){
  require(d != 0)
  //override toString
  override def toString = s"cal values: $n and $d"
}
image
Figure 3 - required

Auxiliary constructors

Sometimes we need multiple constructors in a class. In Scala other than the primary constructor other constructors are called auxiliary constructors.

class Calculator(n: Int, d: Int){
  require(d != 0)
  //override toString
  override def toString = s"cal values: $n and $d"

  // auxiliary constructor
  def this(n: Int) = this(n, 1)
}
image
Figure 4 - Auxiliary Constructor

Method

Now lets define a “add method” in our calculator class where it adds two values.

class Calculator(n: Int, d: Int){
  require(d != 0) //precondition
  //override toString
  override def toString = s"cal values: $n and $d"
  val n1: Int = n
  val n2: Int = d
  var result = 0
  // auxiliary constructor
  def this(n: Int) = this(n, 1)
  //adding two values
  def add() ={
    this.result = this.n1 + n2
    println(s"Add : $n1 + $n2 = $result")
  }
}
val cal = new Calculator(2)
cal.add()
image
Figure 5 - add method

Defining Operators

In scala we can do many interesting things ☺.

Why shouldn’t we use the natural arithmetic operators as methods?

Yes, We can do this in scala ☺.

def * (i: Int) ={
  val demon = this.result
  this.result = this.result * i
  println(s"Multiply : $demon + $i = $result")
}
image
Figure 6 - Method operators

Now we can write cal * 2, we might also want to swap the operands, as in 2 * cal. Unfortunately this does not work yet.

Solution is Implicit

Implicit Conversions

implicit def calToInt (n: Calculator): Int = {
  return n.result
}
val cal = new Calculator(2)
cal.add()
cal * 2
2 * cal
image
Figure 7 - Method operators

We can create an implicit conversion that automatically converts Calculator object to integer when needed. Basically this will help to reduce the code a lot and to reuse the existing methods very effectively. I will discuss later in detail on scala implicit conversion ☺.

So far we saw more aspects of classes in Scala. In next post we will discuss about scala traits.

Blog Series