An analog to a companion object in Java is having a class with static methods. In Scala you would move the static methods to a Companion object.
One of the most common uses of a companion object is to define factory methods for class. An example is case-classes. When a case-class is declared a companion object is created for the case-class with a factory method that has the same signature as the primary constructor of the case class. That is why one can create a case-class like:
MyCaseClass(param1, param2)
. No new element is required for case-class instantiation.A second common use-case for companion objects is to create extractors for the class. I will mention extractors in a future topic. Basically extractors allow matching to work with arbitrary classes.
NOTE: Because the companion object and the class must be defined in the same source file you cannot create them in the interpreter. So copy the following example into a file and run it in script mode:
scala mysourcefile.scala
Example:
- class MyString(val jString:String) {
- private var extraData = ""
- override def toString = jString+extraData
- }
- object MyString {
- def apply(base:String, extras:String) = {
- val s = new MyString(base)
- s.extraData = extras
- s
- }
- def apply(base:String) = new MyString(base)
- }
- println(MyString("hello"," world"))
- println(MyString("hello"))
I am a beginner in Scala.
ReplyDeleteHow test the above code in REPL for Scala?
Appreciate your answer.
Thanks
In the REPL there are a couple of tricks, the easiest is to surround the example in an object:
ReplyDeletescala> object Around {
| class MyString(val jString:String) {
| private var extraData = ""
| override def toString = jString+extraData
| }
| object MyString {
| def apply(base:String, extras:String) = {
| val s = new MyString(base)
| s.extraData = extras
| s
| }
| def apply(base:String) = new MyString(base)
| }
| println(MyString("hello"," world"))
| println(MyString("hello"))
| }
defined module Around
scala> Around
hello world
hello
res5: Around.type = Around$@1ab9dac
Find your posts useful Jesse, thx.
ReplyDeletecopy the code into a file.
ReplyDeleteopen the REPL and type ":load "
(do not include triangular brackets, and do not use quotes around the filename. Use full file pathname)
+1
ReplyDeleteIn the Scala REPL you can use the :paste command to enter paste mode which will allow you to paste in the contents as if it were a single file.
ReplyDeleteDid the ability to access private fields in the class from the companion object change recently in Scala? In 2.10 I get a compile error unless I remove the "private" from "s".
ReplyDeleteIt is also used to resolve implicit parameter
ReplyDeleteHow do you use the companion constructor from another class? In other words, importing it and doing MyString("hello") or new MyString("hello"). I know it works with List, but I've tried your object and another one I'm working on, and am not able to compile any other class that constructs this object!
ReplyDeleteIf you have a Companion object factory method then you just need to do:
ReplyDeleteMyString("hello")