Why is private constructor still visible in case class?

937 Views Asked by At

I want to hide constructor in one class along with its fields and only create instances using a companion object, but I can't achieve that. I have scala 2.13.3 and it's based on java 8. Here is a code sample:

A.scala

package X

object A {
  def apply(x: Int): A = A(Seq(x))
}

case class A private(private val s: Seq[Int])

B.scala

package Y

import X.A

class B {
  val b = A(Seq.empty)
}

And although I wanted to make only apply(x:Int) visible this code compiles so the private constructor is also visible. How can I change this code to work as I expected?

1

There are 1 best solutions below

6
On BEST ANSWER

Make the method A.apply(Seq[Int]) private too

A.scala

package X

object A {
  def apply(x: Int): A = A(Seq(x))
  private def apply(s: Seq[Int]): A = new A(s) // make explicit and private instead of auto-generated and public
}

case class A private(private val s: Seq[Int])

B.scala

package Y

import X.A

class B {
  //val b = A(Seq.empty) // doesn't compile
}

Here the line val b = A(Seq.empty) produces error

Error: polymorphic expression cannot be instantiated to expected type;
 found   : [A]Seq[A]
 required: Int

i.e. the method A.apply(Seq[Int]) is not visible from B.