Protected[$package] vs. private[$package]

Is the declaration protected[package] equivalent to private[package]? I tried a bit around and did not see any difference in the result.

If they are equal: Which should be used? If they are not equal: What is the difference?

Is protected[package] even legal? If so, I have never used it nor seen it.

So, I would say that if you didn’t found any difference then just use private[package] which, AFAIK, is what most people use.

scala> object foo {
     |   trait A { protected[foo] def a = println("a") }
     | }
object foo

scala> object bar {
     |   trait B extends foo.A { def b = a }
     | }
object bar
scala> object foo {
     |   trait A { private[foo] def a = println("a") }
     | }
object foo

scala> object bar {
     |   trait B extends foo.A { def b = a }
     | }
         trait B extends foo.A { def b = a }
                                         ^
On line 2: error: method a in trait A cannot be accessed as a member of bar.B from trait B in object bar
1 Like

Which can also be accomplished with

object foo {
  trait A { protected def a = println("a") }
}


object bar {
  trait B extends foo.A { def b = a }
}

It seems the compiler accepts it, but it does not do anything.

It works the same way as private[foo]. I.e. behave like private/protected outside of foo and behave like public inside of foo.

object foo {
  trait A { protected def a = println("a") }
  def bar(a: A) = a.a
                    ^
On line 3: error: method a in trait A cannot be accessed as a member of foo.A from object foo
        Access to protected method a not permitted because
        enclosing object foo is not a subclass of
        trait A in object foo where target is defined
}
object foo {
  trait A { protected[foo] def a = println("a") }
  def bar(a: A) = a.a
}
1 Like

On a somewhat related note, this code is rejected in Scala 2:

package foo
private class A
class B extends A

Error: private class A escapes its defining scope as part of type foo.A

Instead, private had to be written private[foo]. The issue seems to have been fixed in Scala 3. which accepts a simple private.