Small steps to scala (7/20) - inheritance

Scala
7/20

Inheritance

  • extending a class
  • overriding methods
  • type checks and casts
  • overriding fields
  • abstract classes and fields
  • inheritance hierarchy

Extending a class

Inheritance in Scala works just like in Java. A child class can inherit properties and methods from its parent by using the extend keyword.

This is the parent class

class Vehicle(colour:String) {
  val c: String = colour
  def paint() = println(s"The vehicle is ${c}")
}

And the child class will inherit from its parent:

class Train(colour: String) extends Vehicle(colour) {
   override def paint() = println(s"This train is ${c}")
}

val fast = new Train("Blue")
fast.paint

The above code will return This train is Blue.

Overriding methods.

As shown in the example above, in order to override methods the keyword override will precede the methods to be overridden.

Type check and casts

To check if an object belongs to a certain class, we use the isInstanceOf method and to assign it a certain type, we use the asInstanceOf method.

if(fast.isInstanceOf[Train]) {
   val express = fast.asInstanceOf[Train]
}

Overriding properties

Overriding properties is the same as overriding methods, by using the keyword override in front of the property.

class GreenCar(colour: String) extends Vehicle(colour) {
  override val c: String = "always green"
  override def paint = println(s"This car is ${c}")
}

var car = new GreenCar("Yellow")
car.paint

The above code will return This car is always green since we overridden both the property c and the method paint of the parent class.

Abstract classes

An abstract class is defined with the keyword abstract. Unlike Java, Scala allows concrete methods or properties inside its abstract class.

When extending an abstract class, there is no need to use the override keyword for the abstract methods or properties defined in the class, since they don't really exist in the compiled code.

Those methods and properties need to be properly defined again with val or var in the inheriting class. However, if there is a concrete method or property inside an abstract class, the keyword override is needed.

abstract class Greetings(val greet: String) {
   def hash: Int
   val id: Int = 7 
   var text: String
}

class Hi(val salute: String) extends Greetings(salute) {
   def hash: Int = salute.hashCode
   var text = salute
}

val hi = new Hi("Hello, there! How are you?")
println(s"The greeting ${hi.text} has a hash value of ${hi.hash} and an id of ${hi.id}.")

The code above will produce something like:

The greeting Hello, there! How are you? has a hash value of -650325543 and an id of 7.

If we want to modify (override) the property id:

class Hello(salute: String) extends Greetings(salute) {
   override val id : Int = 10
   var text = salute
   def hash: Int = 999
}

val hello = new Hello("Hey!")
println(s"The greeting ${hello.text} has a hash value of ${hello.hash} and an id of ${hello.id}")

The result will be:

The greeting Hey! has a hash value of 999 and an id of 10.

We can also use anonymous functions to achieve a similar result:

def say(greeting: Hello { def id: Int }): Unit = println(s"The greeting ${greeting.text} has a hash value of ${greeting.hash} and an id of ${greeting.id}.")

val aloha: Hello = new Hello("Aloha!"){override val id = 4321 }

say(aloha)

And the result:

The greeting Aloha! has a hash value of 999 and an id of 4321.

Inheritance hierarchy

The following picture is taken directly from Scala documentation page.

Scala Inheritance Hierarchy

[+] 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
  • Small steps to Scala 6/20 - objects

  • 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.