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.

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 = ???.

Note

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