0

I encountered the following code while checking through a Scala code. I'm finding it difficult to understand what it does.

class Foo(val name: String, val age: Int, val sex: Symbol)

object Foo {
  def apply(name: String, age: Int, sex: Symbol) = new Foo(name, age, sex)
}

Does it add a constructor method to the Class Foo which was already defined?

Is it possible to add extra methods to classes which are already defined using this syntax?

Rogen George
  • 455
  • 1
  • 4
  • 15
  • 1
    you need to read about companion object: http://docs.scala-lang.org/tutorials/tour/singleton-objects.html hope this helps. – Pavel Nov 24 '16 at 16:08
  • 1
    I will give you a very honest opinion. If you can not understand this code, then you have not tried to read the very basics of Scala from any source. So... I will just request you to put some effort before asking on a community like stackoverflow. – sarveshseri Nov 24 '16 at 16:23

5 Answers5

3

Does it add a constructor method to the Class Foo which was already defined?

It adds syntax sugar to the class. Meaning, you can create an instance of Foo like this:

val foo = Foo()

Instead of

val foo = new Foo()

Is it possible to add extra methods to classes which are already defined using this syntax?

In that regards, apply is special as the compiler knows it and expands Foo() to Foo.apply. This means that any other method you want to invoke, you'll have to call the Foo static object, but they will not apply to the Foo instance.

If you want to externally add methods to Foo, you can do so via an implicit class:

implicit class RichFoo(foo: Foo) extends AnyVal {
  def fooDetails(): String = s"{Name: ${foo.name}, Age: ${foo.Age}"
}

Now you can call it on an instance of Foo:

val f = Foo()
println(f.fooDetails())
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
2

In the case, you can think of Foo.apply() as a static method.

Realistically, objects in Scala are implemented as Singleton instances.

Here's the documentation on that.

Himself12794
  • 251
  • 3
  • 13
  • So when I'm referring to Foo in a different file, am I referring the singleton Object or the class? And why do we have companion objects after all ? Why not define the same method in the class definition? – Rogen George Nov 24 '16 at 16:13
  • In this case, the they are using apply() method as a sort of static constructor. In this case though, it might actually be better to use a case class instead. They work better with apply() – Himself12794 Nov 24 '16 at 16:17
  • Companion object its a scala way to implement singleton pattern and its much better than in other languages. Say in C#. – Pavel Nov 24 '16 at 16:18
2

You can invoke any class or object instance in Scala if it has an apply method. What you're doing here is adding a constructor method to Foo's companion object so that when you call it, it will instantiate an instance of Foo.

It is not possible to add methods to an instance with this method. For that, you might be interested in the Scala Pimp My Library pattern which is implemented using implicits.

// the following are equivalent, given your code above

val x = new Foo("Jason", 29, 'Male)
val y = Foo.apply("Jason", 29, 'Male)
val z = Foo("Jason", 29, 'Male)
longshorej
  • 381
  • 1
  • 2
  • Whats the difference between adding a constructor the companion object and adding to the Class itself? – Rogen George Nov 24 '16 at 16:18
  • Scala doesn't have static methods, so if you added it to the class itself, you'd only be able to call it if you already had an instance. Because of this, we use the companion object to house factory methods. – longshorej Nov 24 '16 at 16:20
  • So If I called val a = Foo("Jack",30, 'Male') after your code, what will happen? Does a new object gets created? Or the value of the already existing object of Foo gets changed? – Rogen George Nov 24 '16 at 16:27
  • Yes, a new object is created and `a` will reference it. Everything in the examples so far is immutable (i.e. using `val`); no existing instances can be changed. – longshorej Nov 24 '16 at 16:35
  • Then how can we say that its a singleton If it allows more than one instance of a class to exist? – Rogen George Nov 25 '16 at 05:35
  • Foo, the companion object, is a singleton. Foo and instances of it are not - note that Foo (the companion object) is not an instance of Foo. Hope that helps. – longshorej Nov 25 '16 at 18:07
1

Please read about companion object: http://docs.scala-lang.org/tutorials/tour/singleton-objects.html hope this helps It simplifies object creation for this type. Other way will be to create case class.

Looks like as duplicate to me: Scala: companion object purpose

Community
  • 1
  • 1
Pavel
  • 1,519
  • 21
  • 29
1

This pattern is commonly know as static factory methods. The code you provided is not very useful, but consider these additional factory methods (think of them as "named constructors"):

class Foo(val name: String, val age: Int, val sex: Symbol)

object Foo {
  def apply(name: String, age: Int, sex: Symbol) = new Foo(name, age, sex)
  def newMaleFoo(name:String,age:int) = new Foo(name,age,'male)
  def newPeterFoo(age:int) = new Foo("Peter",age,'male)
}
Raphael Roth
  • 26,751
  • 15
  • 88
  • 145