7

In Java, one of its most common usage is to define a Singleton class. However, since there are no "static" classes in Scala, what are some examples of usages of the Private Constructor?

7
  • 'since there are no "static" classes' What do you mean by that? A Java nested static class can be represented in Scala by defining a class inside a class's companion object (members of companion objects are represented as static members in the generated bytecode), but I don't see what that has to do with the singleton pattern. Commented Mar 13, 2017 at 14:27
  • @sepp2k I think, he means 'static' in terms of C# static. Commented Mar 13, 2017 at 14:31
  • @ZhekaKozlov A static class in the C# sense is a class where all members are static. That also does not apply to singleton classes. Commented Mar 13, 2017 at 14:32
  • @sepp2k No, static classes in C# are singletons Commented Mar 13, 2017 at 14:36
  • 1
    @ZhekaKozlov There are reasons why Java (and C++ etc.) programmers implement the singleton pattern instead of just creating a class where all members are static (and why C# programmers implement the Singleton pattern over using static classes). And these reasons no longer exists if singleton aren't objects. Static classes can't implement interfaces, you can't pass them around and you can't mock them for tests. Commented Mar 13, 2017 at 15:02

2 Answers 2

19

You can access private constructors in the companion object of a class.

That allows you to create alternative ways of creating a new instance of your class without exposing the internal constructor.

I came up with a very quick example of how one might make use of this:

class Foo private(s: String)

object Foo {
  def apply(list: Seq[String]): Foo = {
    new Foo(list.mkString(","))
  }
}

Now you can create new instances of Foo without the new keyword and without exposing the internal constructor, thereby encapsulating the internal implementation.

This can be especially important, as internal implementations might change in the future while the public facing API should remain backwards compatible

Sign up to request clarification or add additional context in comments.

3 Comments

Watch out though, private constructors of case classes still get a corresponding apply method. So you can still call Foo("bar") in your example.
Oops, yeah, didn't intend to make it a case class, must have happened out of habit :D Edited accordingly :)
Thank you for the simple explanation.
3

The use cases of the private constructors are mostly the same as in Java: sometimes you need a full control of how the instances of your classes are created. Consider scala.immutable.Vector. Its constructor is rather complicated:

final class Vector[+A] private(val startIndex: Int, val endIndex: Int, focus: Int)

This constructor is a complex implementation detail which is likely to be changed in the future and therefore should not be exposed to users. Instead, you provide simple factory methods which hide all that complexity of creating instances of vectors: Vector.apply(), Vector.tabulate(), Vector.fill(), ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.