Scala Unit 2
Scala Unit 2
Unit-II
Scala OOPS Concepts - Objects and Class
Object and Class - Singleton object - Companion Objects - Case classes and objects –
Constructors – Method overloading and overriding – Field overriding - Extending a class –
implicit classes – inner classes – Traits - Pattern Matching – Extractors -Collection Classes
Object
Object is a real world entity. It contains state and behavior. Laptop, car, cell phone are the real
world objects. Object typically has two characteristics:
Class
A class is a blueprint for objects. Once you define a class, you can create objects from the class
blueprint with the keyword new. Through the object you can use all functionalities of the
defined class.
In scala, a class can contain:
Data member
Member method
Constructor
Block
Nested class
Super class information etc.
You must initialize all instance variables in the class. There is no default scope. If you don't
specify access scope, it is public. There must be an object in which main method is defined. It
provides starting point for your program. Here, we have created an example of class.
The following diagram demonstrates the class and object by taking an example of class student,
which contains the member variables (name and roll no) and member methods (setName() and
setRollNo()). Finally all are members of the class. Class is a blue print and objects are real here.
In the following diagram, Student is a class and Harini, John, and Maria are the objects of
Student class, those are having name and roll-number.
Basic Class
class Student{
var id:Int = 0; // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student() // Creating an object
println(s.id+" "+s.name);
}
}
Output:
0 null
In scala, you can create class like this also. Here, constructor is created in class definition. This is
called primary constructor.
In scala, you can create anonymous object. An object which has no reference name is called
anonymous object. It is good to create anonymous object when you don't want to reuse it further.
class Arithmetic{
def add(a:Int, b:Int){
var add = a+b;
println("sum = "+add);
}
}
object MainObject{
def main(args:Array[String]){
new Arithmetic().add(10,10);
}
}
Output:
Sum = 20
Singleton Object
Singleton object is an object which is declared by using object keyword instead by class.
No object is required to call methods declared inside singleton object.
In scala, there is no static concept. So scala creates a singleton object to provide entry
point for your program execution.
If you don't create singleton object, your code will compile successfully but will not
produce any output. Methods declared inside Singleton Object are accessible globally. A
singleton object can extend classes and traits.
object Singleton{
def main(args:Array[String]){
object SingletonObject{
def hello(){
In scala, when you have a class with same name as singleton object, it is called
companion class and the singleton object is called companion object.
The companion class and its companion object both must be defined in the same source
file.
class ComapanionClass{
def hello(){
def main(args:Array[String]){
new ComapanionClass().hello()
A Scala Case Class is like a regular class, except it is good for modeling immutable data. It also
serves useful in pattern matching, such a class has a default apply() method which handles object
construction. A scala case class also has all vals, which means they are immutable.
The creation of case class is simple, the keyword case class is used to define it followed by its
name and a set of parameters that can be empty.
Syntax:
case class student(name: String, class: Int, marks: Int, result: String)
Case Objects
The case objects are nothing but the instances of case class in Scala.
obj_name = cc_name(parameter_values)
Could you see and understood, there is no new keyword used in the definition of case object
which is because it uses the apply() method.
Example
case class student(name: String, standard: Int, marks: Int, result: String )
object myObject {
In Scala, case objects can be compared using == expression which returns true or false based on
the comparison.
Syntax:
case_Obj1 == case_Obj2
Example
case class student(name: String, standard: Int, marks: Int, result: String )
object myObject {
We can copy the contents of one case object to another fully and partially too.
Copying case object using copy() method [shallow copy]:
The copy() method on the case object is used to copy the contents of one object to another. This is
a shallow copy.
Syntax:
caseObj1 = caseObj2.copy()
Example
case class student(name: String, standard: Int, marks: Int, result: String )
object myObject {
def main(args: Array[String]) {
// Creating a case Object
val student1 = student("Prem", 10, 89, "A+")
println("Case Object student1 : " + student1)
2.4 Constructors
A constructor is a function that is called at the time of initialization of objects. A constructor is
just like a method of a class that contains instructions to be executed. The constructor has the
same name as the class and is called when the object of the class is initialized.
1) Primary constructor
Also known as default constructor, a primary constructor is created when no other constructor is
defined. It has the same name as the class. It is defined by default in Scala.
Syntax:
Example:
class Student( Sname: String, sub: String)
{
var percentage: Float = 0.0f;
def display()
{
println("Student name: " + Sname);
println("Stream : " + sub);
println("percentage: " + percentage);
}
def this(Sname: String, sub: String, no:Int)
{
this(Sname, sub)
this.percentage = no/5
}
}
object Main
{
def main(args: Array[String])
{
var obj = new Student("kirti", "biology", 345);
obj.display();
}
}
Constructor Overloading
In scala, you can overload constructor. Let's see an example.
class Student(id:Int){
def this(id:Int, name:String)={
this(id)
println(id+" "+name)
}
println(id)
object MainObject{
def main(args:Array[String]){
new Student(101)
new Student(100,"India")
}
}
To create an overloaded method in Scala, define multiple methods with the same name and
different parameter list and return type. This means defining multiple functions one with one
parameter of type ‘A’ other with two parameters, etc.
Syntax:
//Method 1 :
def fun (a : data_type ) {
// code to be executed
}
//Method 2 :
def fun(a : data_type , b : data_type ){
// code to be executed
}
Both these methods contribute to method overloading in Scala. Now, to create an overloaded
method can invert either of the following things in the function that lead to overloading the
method:
object MyClass {
object MyClass {
def datatype(x:Int){
println("The parameter is of Integer datatype")
}
def datatype(x:Float){
println("The parameter is of Float data type")
}
def datatype(x:Char){
println("The parameter is of Character data type")
}
def datatype(x: Boolean){
println("The parameter is of Boolean data type")
}
def main(args: Array[String]) {
println("Program to print data type using method overloading: ")
datatype(4)
datatype(4.0f)
Overriding is the concept in which the child class is allowed to redefine the members of the parent
class. Both methods and variables/ fields can be overridden in object-oriented programming. In
Scala as well both methods and Fields can be overridden but overriding of fields has some
restrictions on implementation.
This program will show what will be the output if override keyword is not used?
class animal{
val voice = "animal's voice"
}
class dog extends animal{
val voice = "Dog bark's...!"
def says(){
println(voice)
}
}
class cat extends animal{
val voice = "cat meow's...!";
def says(){
println(voice)
}
}
object MainObject{
def main(args:Array[String]){
var ani = new dog()
ani.says()
}
}
Output
This program will show what will be the output if override keyword is used?
class animal{
val voice = "animal's voice"
}
class dog extends animal{
override val voice = "Dog bark's...!"
def says(){
println(voice)
}
}
class cat extends animal{
override val voice = "Cat meow's...!";
def says(){
println(voice)
}
}
object MainObject{
def main(args:Array[String]){
var ani = new dog()
ani.says()
var ani2 = new cat()
ani2.says()
}
}
Output
Dog bark's...!
Cat meow's...!
3) Python program with var keyword
This program will show what will be the output if var keyword is used?
class animal{
var voice = "animal's voice"
Example
Note − Methods move() method in Point class and move() method in Location class do not
override the corresponding definitions of move since they are different definitions (for example,
the former take two arguments while the latter take three arguments).
object Demo {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
Syntax
object <object name> {
implicit class <class name>(<Variable>: Data type) {
def <method>(): Unit =
}
}
Example
Let us take an example of an implicit class named IntTimes with the method times(). It means the
times () contain a loop transaction that will execute the given statement in number of times that
we give. Let us assume the given statement is “4 times println (“Hello”)” means the println
(“”Hello”) statement will execute 4 times.
The following is the program for the given example. In this example two object classes are used
(Run and Demo) so that we have to save those two classes in different files with their respective
names as follows.
object Run {
implicit class IntTimes(x: Int) {
def times [A](f: =>A): Unit = {
def loop(current: Int): Unit =
import Run._
object Demo {
def main(args: Array[String]) {
4 times println("hello")
}
}
The following commands are used to compile and execute these two programs.
Command
\>scalac Run.scala
\>scalac Demo.scala
\>scala Demo
Output
Hello
Hello
Hello
Hello
Inner Class is a special concept in Scala using which we can create a class inside another class.
It is used for grouping together classes to improve the usability of the concept of encapsulation in
Scala.
Though Scala inherits many features from Java but, the binding of inner classes. The inner class
in Scala is bound to outer object.
Syntax:
class outerClass{
class innerClass{
// members of innerClass
}
}
Program:
Illustrating the working of the inner class, creating a class inside another class,
// Illustrating the working of inner class
class outerClass{
class innerClass{
def printVal() {
println("This is inner Class from Outer Class!")
}
}
}
object myObjects {
def main(args: Array[String]) {
val outObj = new outerClass()
val inObj = new outObj.innerClass
inObj.printVal
}
}
Output:
This is inner Class from Outer Class!
Syntax:
new outerObject.innerClass().member
Program:
object OuterObject{
class innerClass{
def printVal() {
println("This is inner Class from Outer Object!")
}
}
}
object myObjects {
def main(args: Array[String]) {
val inObj = new OuterObject.innerClass()
inObj.printVal
}
}
Output:
This is inner Class from Outer Object!
Syntax:
new outerClass().innerObject.member
Program:
object myObjects {
def main(args: Array[String]) {
val inObj = new outerClass().innerObject
2.10 Traits
Traits in Scala are like interfaces in Java. A trait can have fields and methods as members,
these members can be abstract and non-abstract while creation of trait.
The implementation of Scala traits can implement a trait in a Scala Class or Object.
Some features of Scala traits:
Members can be abstract as well as concrete members.
A trait can be extended by another trait.
Made using "trait" keyword.
Syntax:
trait trait_name{
def method()
}
object MyClass {
def main(args: Array[String]) {
var v1 = new Ihelp();
v1.greeting
}
}
Output
Hello! This is include Help!
This code prints "Hello! This is include Help!" using trait function redefinition and then calling
that function.
Scala pattern matching: pattern matching feature is check for the equivalence of an object with a
string. In Scala pattern matching classes are strong.
The match keyword is used to define a pattern matching block. This block contain cases that are
that turns that if matched will execute a set of expressions (a block of code).
In Pattern matching, there must be at least one case (also called alternative) with sum values for
which the input pattern can be matched. If no keyword is matched then the last catch-all(_) case
is executed. The expression that is evaluated after the matches found is actually a block code that
is needed to be Evaluated. For a pattern-matching function, any sort of data can be matched
based on first match policy (for you cases matching, the first one is used).
Example:
object Demo {
println(matchno(3))
The case classes are special classes that are used in pattern matching with case expressions.
Syntactically, these are standard classes with a special modifier: case.
Try the following, it is a simple pattern matching example using case class.
Example
object Demo {
person match {
Adding the case keyword causes the compiler to add a number of useful features automatically.
The keyword suggests an association with case expressions in pattern matching.
First, the compiler automatically converts the constructor arguments into immutable
fields (vals). The val keyword is optional. If you want mutable fields, use the var
keyword. So, our constructor argument lists are now shorter.
Second, the compiler automatically implements equals, hashCode, and toString methods
to the class, which use the fields specified as constructor arguments. So, we no longer
need our own toString() methods.
Finally, also, the body of Person class becomes empty because there are no methods that
we need to define!
2.12 Extractors
An extractor is a special type of object that has some special methods. These methods are:
apply() and unapply().
The apply() method of extractor object is used to feeding values for the object, it takes
parameter values, formats them and adds them to the object.
The unapply() method of extractor object is used to delete values from the object, it
matches the value and removes them from the object list.
Working of extractors
Let's take an example of an object that apply() as well as unapply() method. The apply() method
takes arguments and adds them to class. The unapply() does the exact opposite, it takes
arguments, matches them and then deletes, i.e. deconstructs.
Program:
object Student
{
def main(args: Array[String])
{
def apply(name: String, result: String) =
{
name +" is "+ result
}
}
else
None
}
println ("The Apply method returns : " +
apply("Ram", "Pass"))
println ("The Unapply method returns : " +
unapply("RamisPass"))
}
}
A mutable collection is a collection whose elements can be updated and elements are added or
removed from it. It allows all these operations.
An immutable collection does not allow the user to do the update operation or add and remove
operation on it. There is an option to do this, but on every operation, a new collection is created
with updated value and the old one is discarded.
Based on how they have used the collections are classified as lazy or strict. If created as a lazy
collection, it may not consume memory space until they are called by the program.
As the hierarchy is concerned, we have a list of collections, with Traversable trait, it allows
you to traverse the collection i.e. visit each element in the collection one by one. Traversable
has followed another trait Iterable that allows iterating over the elements of the collection.
Here we are listing some commonly used collections that you will encounter in your Scala
programming life. There is a huge base that supports them, this is just an overview;
Scala List
The list is a linear array-like collection. It stores a similar type of elements and uses a linked
list type storage method. List is an immutable collection that extends linearSeq trait.
Scala Tuple
Scala Set
A set is a type collection that contains elements of the same data type, it does not contain any
duplicate elements. Set can mutable as well as immutable in Scala.
Scala Map
A map is a collection that contains key-value pairs. To retrieve the value the key is used.