Skip to main content

OOPs in Scala

Class declaration syntaxes​

Creating simple class in scala

package com.knowbasics

object OppsExample extends App {
val cls = new MyClass
println("The class instance: " + cls)
}
class MyClass
// It prints similar to: The class instance: com.knowbasics.MyClass@71c7db30

Class with parameters

package com.knowbasics

object OppsExample extends App {
val cls = new MyClass("Hello", 20)
println("The class instance: " + cls) // Not possible to access cls.param1 here as class parameters are not fields
}
class MyClass(param1: String, param2: Int) // Constructor
// It would also give similar output: The class instance: com.knowbasics.MyClass@71c7db30

Class with vals in constrctor

package com.knowbasics

object OppsExample extends App {
val cls = new MyClass("Hello", 20)
println("The class instance param2 value: " + cls.param2)
}
class MyClass(param1: String, val param2: Int)
// This will print: The class instance param2 value: 20

Class variables vs function variables and function overloading can be covered here

package com.knowbasics

object OppsExample extends App {
val cls = new MyClass("Hello", 20)
println("The class instance param2 value: " + cls.param2)
cls.test(40)
cls.test()
}

class MyClass(param1: String, val param2: Int) {
def test(param2: Int): Unit = println(s"There is a difference between class param2: ${this.param2}, and function param2 $param2")
def test(): Unit = println(s"This is the function overloading in scala, the class param2: ${this.param2}")
}


/* This will print below three statements

The class instance param2 value: 20
There is a difference between class param2: 20, and function param2 40
This is the function overloading in scala, the class param2: 20

*/

Objects in scala​

In Scala Object are Signleton intances, and would replace static feature of Class in Java. In Scala it would be a wide practice to have an object along with class to handle static kind of varaibles. This pattern is called ** Campanion pattern ** The object will also have factory methods in general. Scala campanions can access each others private memebers.

:::info Note

Scala application has to be declared with sala object with ** def main(args: Array[String]): Unit **. So all your statup code should go into method inside the object. Extending it to App would do same thing.

:::

package com.knowbasics

object MethodNotations extends App {

class Person (val name: String, personAge: Int) {
def apply(): String = "This is apply definition of class"
}
object Person {
val HAS_HANDS = true
def canFly: Boolean = false
}
val ram = new Person("Ramu", 25)

println(Person.HAS_HANDS) //Called with object
println(Person.canFly)
println(ram())
}

Method notation​

Scala supports calling functions in natural language way which is called method notation, below example explains the concept

package com.knowbasics

object MethodNotations extends App {

class Person (val name: String, personAge: Int) {
def isYounger(age: Int): Boolean = age > personAge
def closeFriendOf(person: Person): String = s"${this.name} is close friend of ${person.name} "
}

val raju = new Person ("Raju", 30)
println(raju.isYounger(45))
println (raju isYounger 45) // equivalent

// Infix notation = operator notation
// "operators" in Scala

val ramu = new Person ("Ramu", 40)
println (raju closeFriendOf ramu)

}
/* The result would be like below

true
true
Raju is close friend of Ramu

*/

Operator notations​

By replacing the method name closeFriendOf with an operator + we could achive same result. Please observe below code

package com.knowbasics

object MethodNotations extends App {

class Person (val name: String, personAge: Int) {
def isYounger(age: Int): Boolean = age > personAge
def +(person: Person): String = s"${this.name} is close friend of ${person.name} "
}

val raju = new Person ("Raju", 30)
println(raju.isYounger(45))
println (raju isYounger 45) // equivalent

// Infix notation = operator notation
// "operators" in Scala

val ramu = new Person ("Ramu", 40)
println (raju + ramu)

}
/* The result would be like below

true
true
Raju is close friend of Ramu

*/

This also means you can consider all operators are methods. If you could call a method and pass variable by using syntax obj.methoName(param1), if you are using + operator as your method name then obj.+(param1) would also work.

println( 5 + 3 )
println( 5.+(3) ) //Would give same result

Prefix notation​

The prefix notation would be done using unary operators. There are only 4 unary operators in scala and they are +, -, ~, !, this can also be handled by method ** unary_ **

val x1 = -1
val x2 = 1.unary_- // This would same as above
println(x2) // prints -1

val a = true
val b1 = !a
val b2 = a.unary_! // Both b1, b2 would have same value
println(b2) // prints false

postfix notation​

The postofx notation would allow

package com.knowbasics

import scala.language.postfixOps

object MethodNotations extends App {

class Person (val name: String, personAge: Int) {
def isYounger(age: Int): Boolean = age > personAge
def +(person: Person): String = s"${this.name} is close friend of ${person.name} "

def theName : String = s"The name of person is ${this.name}"
}

val ram = new Person("Ramu", 25)

println(ram.theName)
println(ram theName) //This is a postfixOps call, an advanced feature of scala, would give same result as above

}

apply function​

In scala apply is a special function that can be called with object directly, below example explains how it will work.

package com.knowbasics

object MethodNotations extends App {

class Person (val name: String, personAge: Int) {
def apply(): String = "This is apply definition of class"
}

val ram = new Person("Ramu", 25)

println(ram.apply())
println(ram()) //This would give same result as above
}

Inheritence​

extend​

  • Classes are inherited wiht extend keyword

override​

  • Override keyword is used to override super class methods in child class.

final​

  • A class defined with keyword final or a method written with keyword final can't be extended.

seal​

  • A class defined with keyword seal can be extended with in same file but not outside the file

abstract​

  • A class declared with abstract can't be instansiated, it can only used to extend by other child class.

traits​

  • A trait would be defined using ** trait ** as keyword instead of class keyword.
  • A trait is exteded by a class using ** with ** keyword.
  • A trait is mostly similar to interface??
trait Creatures {
def walk(): Unit
def eat(): Uint
def flyStatus: String = "Can't fly"
}

abstract class Animal {
def numLegs(): Uint
}

class Kangaro extedes Animal with Creatures {
def walk(): Unit = "I can walk"
def eat(): Unit = " I eat veg"
def numLegs(): Uint = "I will use two legs for walk"
}

Type hirarchy​

Scala have few type hirarchy,

Any​

Most uppper class type or mother of all types in scala is scala.Any

AnyRef​

The next level type is scala.AnyRef which is equalent to java.lang.Object in Java

AnyVal​

The type can be used to represent any premitive type, it is not recommanded avoid using as much as possible.

Null​

The scala.Null is a special type which can be used as value for any type that derived from scala.AnyRef.

Nothing​

The scala.Nothing is another type which means nothing exist as value for that variable. The scala.Nothing value can set by ???. Ex: val myTestVar = ???.

:::info Note

While creating class memeber variables or functions, if no access modifier keyworkd provided (private, protected, public), by defualt scala consider it as public.

:::