Kevin Meredith
Kevin Meredith

Reputation: 41909

Restrict Construction of Scala Class

Given:

class Foo(x: Int) {}

object Foo {
  def apply(x: Int) = new Foo(x)
}

Besides marking Foo's constructor as private, how can I present a warning or compile-time failure when calling new Foo(...)?

In other words, I'd like to restrict (either by compile-time warning or error) construction of Foo to Foo.apply.

Is this possible?

Upvotes: 1

Views: 724

Answers (1)

Aivean
Aivean

Reputation: 10882

In scala there are two idiomatic ways how to achieve that.

  1. Constructor private to the class and companion object.

Factory has access to constructor, while anyone else doesn't:

class Foo private[Foo](val x: Int)

object Foo {
  def apply(x:Int) = new Foo(x)
}

val foo = new Foo(1)  // cannot compile
val foo1 = Foo(1) //compiles fine
  1. Sealed abstract class.

In scala sealed class can be extended only in the same source file it is defined. I suggest to make Foo sealed abstract class and return anonymous child of Foo in object's apply method.

sealed abstract class Foo(val x:Int)

object Foo {
  def apply(x:Int):Foo = new Foo(x) {}
}

In this case Foo can be created nowhere except the file where it is defined.

UPD: Actually, this question was already discussed on stackoverflow.

UPD2: Added brief overview of both methods.

Upvotes: 7

Related Questions