Small steps to scala (6/20) - objects

Scala
6/20

Objects

In Scala everything is an object. While in Java there is a distinction between primitive types and reference types, Scala does not have that. For example numbers, expressions, functions are all objects.

In the Java meaning of the word, an object is an instance of a class and that is true for Scala also. However, in Scala, the keyword object has an extra meaning.

  • inside an object, you can define a main class as the starting point of a Scala application
  • the keyword is used to define the equivalent of a Java static class
  • and finally, it is used to create a so called companion objects

Application objects

Paste the following code inside a file called Hello.scala:

object HelloScala {
    def main(args: Array[String]) {
        println("Hello, Scala!")
    }
}

And then compile it using the command: scalac Hello.scala.
To run the binary, execute the following command:

> scala -classpath . HelloScala
Hello, Scala!

It is also possible to type the above code into the Scala REPL and run it from there.

scala> :paste
// Entering paste mode (ctrl-D to finish)

object HelloScala {  
    def main(args: Array[String]) {
        println("Hello, Scala!")
    }
}

// Exiting paste mode, now interpreting. <<< Press Ctr + D here

defined object HelloScala

scala> HelloScala.main(Array(""))
Hello, Scala!

All Scala programs must have a main method, where the program starts.

It is however possible to have an executable Scala program without the main method. In this case, you need to extend the App trait, as shown in the example below.

object HelloAgain extends App {  
        println("Hello, Scala! Look, no main!")
}

Note the result in REPL! You still need to call the main method, although it wasn't specifically defined in the object.

scala> HelloAgain.main(Array())
Hello, Scala! Look, no main!

Like Java static classes

object Rand100 {
    var top = scala.util.Random
    
    def getRand = top.nextInt(100)
}

In order to call the method getRand all you have to do is:
Rand100.getRand and it will return an Int rand between 0 and 100.

Companion objects

Companion objects in Scala are objects with the same name as the class and it is defined inside the same file. A companion object is similar to having a class with static methods.

The companion object has access to all methods and properties of the class even if they are private. As mentioned earlier, everything in Scala is an object. However, if you want to treat an object like a function, you can use the apply method.

class myString(val aString: String) {
    private var extraString = ""
    override def toString = aString + extraString
}

object myString {
    def apply(base: String, extras:String) = {
        val s = new myString(base)
        s.extraString = extras
        s
    }
    
    def apply(base: String) = new myString(base)
}

Calling the object above using one and two arguments:

scala> println(myString("Hello"))
Hello
scala> println(myString("Hello", ", World"))
Hello, World

Objects extending a class or a trait

You extend classes in Scala the same way you do in Java.

import java.io._

class Point(val xc: Int, val yc: Int) {
    var x: Int = xc
    var y: Int = yc

    def move(dx: Int, dy: Int) {
        x = x + dx
        y = y + dy
        println("Point x location: " + x)
        println("Point y location: " + y)
    }
}

class Location(override val xc: Int, override val yc: Int, val zc: Int) extends Point(xc, yc) {
    var z: Int = zc

    def move(dx: Int, dy: Int, dz: Int) {
        x = x + dx
        y = y + dy
        z = z + dz

        println("Point x location: " + x)
        println("Point y location: " + y)
        println("Point z location: " + z)
    }
}

object Test0 {
    def main(args: Array[String]) {
        val loc = new Location(10, 10, 10)

        // move to a new location
        loc.move(1, 2, 3)
    }
}

Running the code above

scala> Test0.main(Array(""))
Point x location: 11
Point y location: 12
Point z location: 13

An example using traits and classes.

trait Equal {
    def isEqual(x: Any): Boolean
    def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
    var x: Int = xc
    var y: Int = yc
    def isEqual(obj: Any): Boolean = { obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x }
}

object Test1 {
    def main(args: Array[String]) {
        val p0 = new Point(2, 2)
        val p1 = new Point(2, 2)
        val p2 = new Point(1, 3)

        println(p1.isEqual(p0))
        println(p1.isEqual(p2))
        println(p2.isNotEqual(p0))
        println(p0.isEqual(3))
        println(p2.isNotEqual((4,1)))
    }
}

The result:

scala> Test1.main(Array())
true
false
true
false
true

[+] Scala series
  • Small steps to Scala 1/20 - the basics
  • Small steps to Scala 2/20 - functions
  • Small steps to Scala 3/20 - arrays
  • Small steps to Scala 4/20 - maps and tuples
  • Small steps to Scala 5/20- classes

  • Disclaimer: This is by no means an original work it is merely meant to serve as a compilation of thoughts, code snippets and teachings from different sources.