In this blog, I am going to discuss about the most important feature of the OOPs language, i.e., Classes and Objects in Scala.
What is a Scala Class ?
Scala classes are blueprint or template for creating objects. Moreover they contain information of fields, methods, constructor, super classes, etc. So with the help of class keyword we can define the class.
To access the members of the class we need to create an object of the class. So with the help of the new keyword we can create an object of class.
However if no class is extend explicitly then AnyRef is use. Below is the example to show how to create class and and its object
What are Singleton Objects?
In Scala there is no static concept instead of that Scala has Singleton object. Singleton object is declared by using object keyword. Also no object is required to call methods declared inside singleton object. That’s why singleton object is also use to provide entry point for your program execution. Also we can access the member of singleton object by using object name. So Below is the example to create singleton object and how to access the member of the singleton object
What is Companion object?
Companion object is defined in the same source file in which the class is defined with the same name as of the class. Also it is allowed to access both private methods and private fields of the class. Below is the example how to create companion object in Scala
What is Case class?
One of the most important feature of the Scala is case class . It is like a regular class, except it is good for modeling immutable data. It also used in pattern matching, such a class has a default apply() method which handles object construction. Compiler creates nice toString, equals and hashcode method. Moreover to create case class in Scala we need the keywords ‘case class’, an identifier, and a parameter list. You can keep the parameter list empty and case class body is optional.
For eg, case class Person(name:String)
It also provides apply method which allows us to create an object without new keyword.
val person=Person(“Akash”)
To access the name of the person person.name, we can not reassign the value of the field name like this person.name=”Amit” because case class fields are immutable.
Lets explore what compiler actually do when we create the case class
case class Note(name: String, duration: String, octave: Int)
case class expanded form
class Note(_name: String, _duration: String, _octave: Int) extends Serializable {
// Constructor parameters are promoted to members
val name = _name
val duration = _duration
val octave = _octave
// Equality redefinition
override def equals(other: Any): Boolean = other match {
case that: Note =>
(that canEqual this) &&
name == that.name &&
duration == that.duration &&
octave == that.octave
case _ => false
}
def canEqual(other: Any): Boolean = other.isInstanceOf[Note]
// Java hashCode redefinition according to equality
override def hashCode(): Int = {
val state = Seq(name, duration, octave)
state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
}
// toString redefinition to return the value of an instance instead of its memory addres
override def toString = s"Note($name,$duration,$octave)"
// Create a copy of a case class, with potentially modified field values
def copy(name: String = name, duration: String = duration, octave: Int = octave): Note =
new Note(name, duration, octave)
}
object Note {
// Constructor that allows the omission of the `new` keyword
def apply(name: String, duration: String, octave: Int): Note =
new Note(name, duration, octave)
// Extractor for pattern matching
def unapply(note: Note): Option[(String, String, Int)] =
if (note eq null) None
else Some((note.name, note.duration, note.octave))
}
