3

Suppose I have two classes:

private[example] class PoorInt    extends Int
class RichInt    private[example] extends Int

The question is what's the difference between private modifier position in these classes declarations?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Finkelson
  • 2,921
  • 4
  • 31
  • 49

1 Answers1

6

The first refers to the scope of the class, i.e. you cannot access PoorInt outside package example.

The second refers to the scope of the constructor of RichInt, which you are not providing explicitly, i.e. you cannot use its constructor outside package example.

For example:

// somewhere outside package example ...
val x = new RichInt // doesn't compile. Constructor is private
val y : PoorInt = ... // doesn't compile. PoorInt is not accessible from here
def f(x: PoorInt) = ... // doesn't compile. PoorInt is not accessible from here

You can also see this question.

Community
  • 1
  • 1
ale64bit
  • 6,232
  • 3
  • 24
  • 44
  • It's weird because when I add a companion object to PoorInt, then all works fine: `object PoorInt { def apply() = new PoorInt }`. It makes PoorInt accessible. – Finkelson Jul 09 '16 at 08:30
  • what do you mean by "accessible" in this case? The companion can be accessible while the class itself could be not accessible (due to private modifier), e.g. you may be able to write `val y = PoorInt()` since both the companion and apply method are public, but you cannot write `val y: PoorInt = PoorInt()`, due to the type itself being private. Please, provide a concrete example so that others can reproduce the problem exactly. – ale64bit Jul 09 '16 at 08:39
  • 1
    @Finkelson nothing strange there - the companion object has access to the private parts of its companion class (and vice versa). – Jesper Jul 09 '16 at 09:04
  • What If I would declare such class `class B private () { def apply(i: Int) = new B }`. In that case instantiating of B via `new B(1)` in the other package would cause an error however I declare a public constructor `apply(i: Int)`. So I guess `private` restrictions spread on all constructors. – Finkelson Jul 09 '16 at 09:06
  • @Finkelson if you want to overload/create another constructor, you need to use `this` as method name, i.e. `def this(i: Int) = this()`, and not `def apply(i: Int) = new B` as you propose. OTOH, you can put this `apply` method in the companion object of `B` for the same purpose. – ale64bit Jul 09 '16 at 09:13
  • I'm totally confused. If I declare a class `class B private[test]() { def this(i: Int) = this }` in package `test.b`, then it is possible to instantiate it from `object E extends App { val b = new B }` which is in `test` package. – Finkelson Jul 09 '16 at 09:37
  • You can instantiate it because `E` is in the scope of `private[test]`, as it is declared inside the same package. – Yuval Itzchakov Jul 09 '16 at 09:44
  • @Finkelson `def apply(i: Int)` is a method on `B`, it can be used as `val b: B = ...; b(1)`. – Alexey Romanov Jul 09 '16 at 10:39