protected inner class escapes its defining scope

410 views
Skip to first unread message

HjP

unread,
Sep 20, 2012, 9:10:13 AM9/20/12
to scala...@googlegroups.com
When I compile the following code I get the error "private class Inner escapes its defining scope..":

class Outer {
  private class Inner {}
  def f = new Inner()
}

Why does this error vanish when I replace "private" by "protected" ?

Erik Osheim

unread,
Sep 20, 2012, 9:55:24 AM9/20/12
to HjP, scala...@googlegroups.com
So, if 'f' is a public method, what is the type signature of f? Clearly
it has to mention a private class, which is not legal.

By contrast, the following is fine:

trait Widget

class Outer {
private class Inner extends Widget
def ok: Widget = new Inner()
}

Hope this helps!

-- Erik

Michael Swierczek

unread,
Sep 20, 2012, 10:17:02 AM9/20/12
to Erik Osheim, HjP, scala...@googlegroups.com
I believe Hjalmar Peters' confusion, which I share, is that
"protected" in Scala means that the declared class, object, method,
val, etc... can only be accessed by itself and its subclasses.
I would expect
class Outer {
protected class Inner {}
def f = new Inner()
}
to still fail to compile because I would expect protected Inner not to
be in scope for 'f'.
What am I missing?

-Mike

Erik Osheim

unread,
Sep 20, 2012, 10:26:18 AM9/20/12
to Michael Swierczek, HjP, scala...@googlegroups.com
On Thu, Sep 20, 2012 at 10:17:02AM -0400, Michael Swierczek wrote:
> I believe Hjalmar Peters' confusion, which I share, is that
> "protected" in Scala means that the declared class, object, method,
> val, etc... can only be accessed by itself and its subclasses.

I think you're slightly confused. A protected inner class can only be
accessed by its *enclosing* class and subclasses. The Scala compiler
will enforce this constraint (although it won't be reflected in the
Java bytecode AFAIK):

class Outer {
protected class Inner
def inner() = new Inner()
}

class Related extends Outer {
def ok() = new Related().inner()
def fails() = new Outer().inner()
}

class Unrelated {
def alsoFails() = new Outer().inner()
def stillFails() = new Related().inner()

Michael Swierczek

unread,
Sep 20, 2012, 10:46:20 AM9/20/12
to Erik Osheim, HjP, scala...@googlegroups.com
Thanks for the clarification. I have Programming in Scala (Odersky,
Spoon, Venners, first edition) and my read of the access modifiers
section was that enclosing classes were not included when using
protected. I was wrong.

-Mike

Erik Osheim

unread,
Sep 20, 2012, 11:30:23 AM9/20/12
to Michael Swierczek, HjP, scala...@googlegroups.com
On Thu, Sep 20, 2012 at 10:26:18AM -0400, Erik Osheim wrote:
> I think you're slightly confused. A protected inner class can only be
> accessed by its *enclosing* class and subclasses. The Scala compiler
> will enforce this constraint (although it won't be reflected in the
> Java bytecode AFAIK):

Just want to apologize to the list. Paul Phillips pointed out to me
that I must have been doing something wrong, because when Inner is
protected all of these methods compile.

I'm not totally sure what went wrong. I guess the take-away is that
unlike private, protected inner classes don't impose a lot of access
restrictions on the outside world.

Sorry,

-- Erik

HjP

unread,
Sep 20, 2012, 12:52:59 PM9/20/12
to scala...@googlegroups.com
So, again my initial question: Why is a protected inner class (unlike a private inner class) allowed to escape its defining scope?
Reply all
Reply to author
Forward
0 new messages