Juh_
Juh_

Reputation: 15539

how to call a subclass constructor with constrained access?

I have something like below that I want to compile

trait T{
  def a: Int
}

class A private(val a: Int, a2: Int) extends T{
  def add(b: Int): A = new A(a + b, a2 + 2*b)
}

object T{
  def make(a: Int): A = {
    new A(a, 2*a) // doesn't compile
}

Here class A has a private constructor because I want the only way to construct a A is to pass through the constructor T.make or with the updated method A.add (which in this example both garantie that a2 = 2*a).

But because A constructor is private, it cannot be access by the parent trait T. Same goes for protected. Basically, I would need an inversed protected?

Note: A solution that is not satisfying is to lower (too much) the restriction on A constructor, maybe to package-private. But I don't want any other construction possible but the ones that were planned. I could lower the constraint to all code in the current file, but I don't know how to do that either.

Upvotes: 1

Views: 89

Answers (2)

Dima
Dima

Reputation: 40500

A few options.

  • You can rename your object T to object A - then it will have access to A's private members

  • You can make class A inner to object T - then you can make the constructor private[T], and T will have access to it.

  • You can also make it package-private. You are mistaken when you say that it would be "lowering restriction too much". A package in scala doesn't have to be an entire directory. It doesn't even need to be the whole file. You have complete control over its content, and the purpose of that is to be able to do exactly what you are trying to do here.

Upvotes: 4

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

Maybe you should put make(..) into companion object of class A rather than companion object of trait T.

  object A  {
    def make(a: Int): A = {
      new A(a, 2 * a) 
    }
  }

Upvotes: 3

Related Questions