Re: inner class scope issues
jrobinss wrote:
How come I can call a method with super.method() when it's private in
the superclass?
Because 'super' means "get at the members through my core that is of
the super-type." Nested classes have access to outer private members,
so the 'super' invocation works. What the nested class instance is
accessing is *its own* code for 'method()', not some other instance's.
Here are my thoughts on the subject...
public class SomeSuperClass {
public static class SomeInnerClass extends SomeSuperClass {
It is contradictory to name a static nested class with the word
"Inner". In Java, "inner classes" are non-static member classes.
private void someInnerMethod() {
somePrivateStaticMethod();
This works because it's in a static context, so all is ok, and it's a
nested class calling a private member, which is also ok.
Correct.
this.somePrivateMethod(); // compile error
This doesn't work because it's trying to reach a private method of the
superclass *as though it were inherited*, which it is not.
Correct.
The method being private, it can't be accessed by a subclass.
Wrong. It can be accessed if the subclass is nested, as it is here.
Of course, the result is the same without "this.".
Wrong, sort of. The reason it fails without 'this' is that the method
call does not have an owning instance.
super.somePrivateMethod(); // works fine!
This is the interesting part.
This is ok because...
#1) we need access: SomeInnerClass is a nested class, so access to
private members is ok
Correct.
#2) we need an instance, because the method is not static (and the
nested class is static): we have super, which is an instance.
Not completely correct. 'super' is this instance, not just any
instance. 'super' means "'this' taken as an instance of the
supertype".
So we see that if it wasn't a subclass *and* nested, this wouldn't
work.
I think what gets me wondering is that to understand this, I need to
see SomeInnerClass not as "being a" SomeSuperClass (which is the OO
way of thinking generally advocated), but rather see SomeInnerClass
has having a pointer, called "super", to an instance of
SomeSuperClass.
Not really. It's not "an instance", it's "this instance".
Let's say it differently: I used to see a subclass as "being a"
superclass, but with no access to superclass's private members.
A subtype still "is-a" supertype. It is also still true that a nested
subtype does not inherit its supertype's private members.
If I keep this point of view, the access should be ok because it's nested=
..
So I need to see a subclass as being a superclass, but *without* the
superclass's private members (not with them but with no access).
Not true. The subclass still does have those private superclass
members, it just doesn't inherit them.
The question of access to private members of an outer class is
orthogonal to inheritance, unrelated.
This makes it work out: this.somePrivateMethod() is not ok, because
although I could call somePrivateMethod() on SomeSuperClass, the
method doesn't exist in SomeInnerClass, and being nested doesn't
change anything about its existence.
Wrong. The method does exist in the misnamed 'SomeInnerClass'.
Note that this works:
((SomeSuperClass)this).somePrivateMethod(); // works fine!
That's semantically equivalent to calling 'super.somePrivateMethod()'.
I'm still left wondering if the compiler couldn't have said ok for
this.somePrivateMethod()...
No.
#1 and #2 above are both true after all, I've got an instance,
and I've got access to this method because of nesting.
Not enough. You need inheritance, which does not apply to private
members.
--
Lew