Re: inner class scope issues
jrobinss wrote:
Hi all,
[SSCCE at end of post]
I don't understand the scope of attributes & methods for an inner
static class. Although I learnt a lot doing the research to write this
message! :-)
I followed the previous conversation and I learned a lot also. I hadn't
really consider that enums might be a static class. Wild, but
apparently true.
However, I think there's still one little thing you are hung up on.
Taking your last SSCCE:
package enumTests;
public class SomeSuperClass {
public static class SomeInnerClass extends SomeSuperClass {
private void someInnerMethod() {
somePrivateStaticMethod();
this.somePrivateMethod(); // compile error
super.somePrivateMethod(); // works fine!
this.someProtectedMethod();
}
}
private void somePrivateMethod() {}
static private void somePrivateStaticMethod() {}
protected void someProtectedMethod() {}
}
Now compare with this:
public class SomeSuperClass {
private void somePrivateMethod() {}
static class StaticNested {
public void staticNestedMethod( SomeSuperClass x ) {
x.somePrivateMethod();
}
}
class InnerClass {
public void innerMethod() {
somePrivateMethod();
}
}
class InnerChildClass extends SomeSuperClass {
public void innerMethod() {
somePrivateMethod();
}
}
static class StaticNestedChildClass extends SomeSuperClass {
public void staticNestedMethod() {
super.somePrivateMethod();
}
}
}
First, all nested (inner classes and static nested classes) have access
to all private members of their enclosing class. This means variables
as well as methods. So where I've written somePrivateMethod() I could
have just as easily put a variable from SomeSuperClass.
The first class, StaticNested, accesses somePrivateMethod through an
instance of SomeSuperClass. Note that this is ANY instance, not just an
enclosing one. Static classes have no enclosing instance, they're
really just two disjoint classes in every way, except that they can
access each other's private members (sounds naughty, eh?). This is a
lot like the friend keyword in C++. Something to keep in mind.
The second class, InnerClass, just accesses somePrivateMethod(). It uses
no qualifiers. Normal scope resolution rules means that the compiler
first checks InnerClass for any matching methods, and finding none
proceed outwards to SomeSuperClass, where it finds the match. This
could cause confusing if field or method names where close in spelling
between an InnerClass and it's outer class. I prefer to design the
names so they are different enough that no confusion occurs.
Next, look at InnerChildClass. Again, no qualifiers are needed.
somePrivateMethod is in scope, and can be called directly without
resorting to the super keyword.
Finally, observe that the StaticNestedChildClass follows much the same
pattern as InnerChildClass. I do find it surprising that super is
allowed here. However, since the private method is in scope (just like
the above three examples) I don't think it should be too surprising.
You can add super to the method call in InnerChildClass:
class InnerChildClass extends SomeSuperClass {
public void innerMethod() {
super.somePrivateMethod();
}
}
And this changes nothing. The "super" is redundant. For
StaticNestedChildClass, the super is required, but otherwise the pattern
is the same. It's a bit like adding "this" whenever a class calls its
own instance methods: redundant, but the compiler accepts it.
Anyway, hopefully approaching it from this direction has helped out
somebody besides me. :)