ziggystar
ziggystar

Reputation: 28676

Scala protected constructor and builder in companion object

I have some classes with a protected constructor and the factory method is inside the companion object of an abstract super class. As of Scala 2.9.0.RC4 this doesn't compile anymore. I have "fixed" the issue by making the constructors package protected. But I don't want other classes even inside the same package to be able to call the constructors.

So what should I?

sealed abstract class A
object A {
  //the factory method, returning either a B or C
  def apply(): A
}
class B protected (...) extends A
class C protected (...) extends A

Upvotes: 2

Views: 1246

Answers (3)

Christoph Hösler
Christoph Hösler

Reputation: 1274

Another option is to create companion objects for each implementation of A and delegate construction to a factory method in this object:

sealed abstract class A
object A {
  //the factory method, returning either a B or C
  def apply(): A = {
    if (...) B()
    else C()
  }
}
object B {
  def apply() : B = new B()
}
class B private (...) extends A

object C {
  def apply() : C = new C()
}
class C private (...) extends A

Upvotes: 0

Kim Stebel
Kim Stebel

Reputation: 42045

Since you need the classes accessible for pattern matching, I would suggest creating a new subpackage for them and making the constructor private to that package. Now only the import statements in your client code need to be changed.

sealed abstract class A {

}
package myPackage.subPackage {

object A {
  def apply(): A = new B
}

class B private[subPackage] () extends A {

}
}

package other {
  object Foo {
    def foo {
      myPackage.subPackage.A()
      //does not compile: new myPackage.subPackage.B
    }
  }
}

Upvotes: 1

Kim Stebel
Kim Stebel

Reputation: 42045

You could make them private inner classes of the object.

object A {
  private class B extends A
  private class C extends A
}

Upvotes: 1

Related Questions