In Previous chapter we learned about SCALA CLASS and today lets check out SCALA SINGLETON AND COMPANION OBJECT.
From previous chapter we now know how to create an instance of a class using the new keyword. Let’s recap
scala> class student(name:String) defined class student scala> val obj1 = new student("Smith") obj1: student = student@7c93e69 scala> val obj1 = new student("Alex") obj1: student = student@7bbe532b
Here obj1 and obj2 are instance of class Student. Notice that i am not calling obj1 and obj2 as Objects. The reason being in Scala , objects are different from instance of a class. A Scala Object is a type of class for which only one instance can be initiated, they are also known as Singleton Objects.
Table of Contents
SCALA SINGLETON OBJECT
A Singleton object is a type of class for which only one instance is created. The syntax of a singleton object is same as a class but instead of using Class keyword we use ‘object’.
Lets look at the HOW WHY & WHEN
How to create a Scala Singleton Object
As mentioned above the syntax is same as that of a class but we use the keyword object. As only a single instance is created and we cannot initialize , an object does not take any parameters.
scala> object student defined object student
When is a Singleton Object Instantiated
When we say that only one instance is created that does not mean we have to create it using new Keyword. The instance is created automatically when we use the object for the first time.
Lets see this as an example
scala> object student{ | println("Object Instantiated") | def prt = println("Inside Student Class") | } defined object student scala> student.prt Object Instantiated Inside Student Class scala> student.prt Inside Student Class
When object.prt was called first the object was instantitated and then the method was called. But when we call it again only the method is called.
Why is a Singleton Object used
A singleton object is used to house all the global or utility method and also Global Constants. What this means is if you have a method that needs to be used across your project you can keep them in a Singleton Object and use them without instantiating. You also use them to create Singleton Design Patterns.
Suppose you have a method which identifies if the password entered is a weak or strong password, then you can create this method in a Singleton Object and share it with your team members to use it wherever required.
We learned that a singleton object does not take any parameters. You can still implement it using Apply Method. Lets learn more about it
SCALA APPLY METHOD
Both Scala Class and Object have a default method known as ‘APPLY‘ .If you create a method in object named APPLY, then you can directly pass parameters to the object. Lets check this with an example
scala> object student{ | def name(nm:String) = println(s"Student name is $nm") | def apply(age:Int) = println(s"Student age is $age") | } defined object student scala> student.name("Smith") Student name is Smith scala> student(23) Student age is 23
In the above code we have created a Singleton Object named Student which has 2 methods. You see that to call method ‘name’ i had to call student.name() , but to call the apply method I simply pass the parameter to the object student. Note that you can create multiple apply methods and the compiler will identify the correct method based on number of parameters or the datatype of parameters.
scala> object student{ | def apply(age:Int) = println(s"Student age is $age") | def apply(age:Int , nm:String) = println(s"Student name is $nm and age is $age") | def apply(fnm:String , lnm:String) = println(s"Student first name is $fnm and last name is $lnm") | } defined object student scala> student(23) Student age is 23 scala> student(23,"Smith") Student name is Smith and age is 23 scala> student("Smith","Hope") Student first name is Smith and last name is Hope
SCALA COMPANION OBJECT
When class name and object name are same and declared in the same file then the object is known as companion object. In the below example student object is the companion object of student class.
scala> :paste // Entering paste mode (ctrl-D to finish) class student{} object student{} // Exiting paste mode, now interpreting. defined class student defined object student
Note: When creating companion object use the :paste function to paste both class and object together, else they won’t be considered as companion object.
WHY TO CREATE A SCALA COMPANION OBJECT
Scala wants to separate the class level fields and methods from the static/global level fields and methods. In other words, the members for which we need to instantiate can be placed in class and factory/ uitlity methods can be placed in object.
Lets check the example below
scala> :paste // Entering paste mode (ctrl-D to finish) class school{ var schoolname:String = "" var admission_cnt:Int = 0 var total_cnt:Int = 0 def updtcnt ={ total_cnt = school.count(admission_cnt,total_cnt) } def prt = println("Total number of students admission in " + schoolname + " is " + total_cnt) } object school{ def count(admcnt:Int ,cnt: Int) = { admcnt + cnt } } // Exiting paste mode, now interpreting. defined class school defined object school scala> val cm = new school cm: school = school@76a7f2fa scala> cm.schoolname = "Cambridge" cm.schoolname: String = Cambridge scala> cm.admission_cnt = 10 cm.admission_cnt: Int = 10 scala> cm.updtcnt scala> cm.prt Total number of students admission in Cambridge is 10 scala> val hw = new school hw: school = school@518a9c8a scala> hw.schoolname = "Howards" hw.schoolname: String = Howards scala> hw.admission_cnt = 15 hw.admission_cnt: Int = 15 scala> hw.updtcnt scala> hw.prt Total number of students admission in Howards is 15 scala> cm.admission_cnt = 16 cm.admission_cnt: Int = 16 scala> cm.updtcnt scala> cm.prt Total number of students admission in Cambridge is 26
In the above example we have a class school and companion object school. Now the class stores the school name ,student admission per day and total admission till date. These members belong to class as they will be different for each SCHOOL.
But the method to find sum of total student already admitted plus new students can be present in companion object as these is a common method to be used by every instance of class.
So here we can ask, can’t the same be done without companion object. Instead of creating an object school I could have created a singleton object named sum, to add the student count. The answer is both yes and no, if any member was private in the class the singleton object couldn’t have used it but a companion object can. So remember, a companion object and class can access each others private members.
APPLY METHOD IN COMPANION OBJECT
Apply method in companion object is used to create an instance of the object without calling the new keyword. As you can see in the below email i am creating an object without using the new keyword.
scala> :paste // Entering paste mode (ctrl-D to finish) class student(nm :String){println(nm)} object student{ def apply(str:String) = new student(str) } // Exiting paste mode, now interpreting. defined class student defined object student scala> val nm1 = student("Smith") Smith nm1: student = student@372741bb scala> val nm2 = student("Bravo") Bravo nm2: student = student@1bb3390e
In the next chapter we will learn about SCALA CASE CLASSES.
Thanks for the simplification of single and companion objects in scala. Please explain the details in another blogs with more examples