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.
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 = ???.
While creating class memeber variables or functions, if no access modifier keyworkd provided (private, protected, public), by defualt scala consider it as public.