To everyone who has helped me by replying to this, thank you!
My confusion started with the explanation of inner classes as "getting
access to the members of its enclosing class". From this I assumed that this
access was just made available, also to the inner class's callable
interface. In other words, I thought it was bigger than it actually was.
To use the example from Chris Smith:
public class Test
{
public static void main(String[] args)
{
new Test2().new TestInner().printMessage();
}
}
class Test2
{
public void printMessage()
{
System.out.println("Test message");
}
class TestInner
{
}
}
Yes, I can see now that this doesn't work. However, the call here to
printMessage(), had it been done within the class TestInner, would have.
The principles of "hiding" members from the outer class from within the
inner class have many parallels with overriding, so it is easy to get
confused. My dissatisfaction started because I realised I could "hide" a
method from the outer class by making one with an identical signature from
an inner class, but once I did that I could never actually get a-hold of the
outer class with something like "super". But more about this later.
First, two observations:
First observation: the literature makes a *real* lousy job of explaining
this. Take Heller&Roberts book "Complete Java 2 Certification Study Guide
Fourth Edition". When they talk about reusing method names, very
specifically, they say "As you construct classes and add methods to them, in
some circumstances you will want to re-use the same name for a method. You
can do so two ways with Java. Re-using the same method name with different
arguments and perhaps a different return type is known as overloading. Using
the same method name with identical arguments and return type is known as
overriding." Apparantly this statement is incorrect or at best incomplete -
there is also this "hiding" thing. Since what I was doing was using the same
method name with identical arguments and return type, well, it just *had* to
be overriding, right? Well, sure shows me!
As a second example, take Peter van der Linden's book "Just Java 2 - Fifth
edition". He says, in his chapter on Polymorphism: "Polymorphism is a
complicated name for a straightforward concept. It is Greek for 'many
shapes' and it merely means using the same one name to refer to different
methods. 'Name reuse' would be a better term. There are two types of
polymorphism in Java: the really easy kind (overloading) and the interesting
kind (overriding)." Same thing here, there's nothing on this hiding trick
you do with inner classes.
Second observation, this "hiding" principle is still iffy. Even if it it's
true that an inner class does not override the methods of its outer class
(as Chris and others have demonstrated) still it is possible for an inner
class to extend one of the methods of the outer class, much like a subclass
would do for its parent. Fortunately I read a bit from Bruce Eckel's book
where he explains this - and I've made a sample program to demonstrate:
package temptests;
class inners2
{
void printMessage()
{
System.out.println("hidiho");
}
public static void main(String[] args)
{
outerclass01 oc001 = new outerclass01();
outerclass01.sucker t2 = oc001.new sucker();
t2.lemmeSee();
}
}
class outerclass01
{
void printMessage()
{
System.out.println("deedledeedledeedle");
}
class sucker extends inners2
{
void printMessage()
{
System.out.println("feefifofum");
}
void lemmeSee()
{
printMessage();
super.printMessage();
outerclass01.this.printMessage();
}
}
}
The output is "feefifofum" "hidiho" and "deedledeedledeedle". This mechanism
enables me to extend methods with identical names, coming from two wholly
unrelated classes (outerclass01 and inners2). While it's great that this
sort of stuff is possible, I do believe, however, that it violates the
spirit of what they were trying to do when they specified no multiple
inheritance in Java.
I would be interested if somebody strongly disagreed with this.
Thanks,
Ben.
Ben Wilson said:
Hi, I'm hoping someone out there is an expert and can share some
authoritative insights.
I'm working with inner classes in Java, and I'm finding myself unsatisfied
with the way they've been implemented, and frankly, somewhat alarmed. It is
true that an inner class can access the methods and object variables of its
enclosing class. However, it is also true that inner classes participate in
overriding - I can set up an inner class that overrides the members of its
enclosing class. However, inner classes can also be defined to extend
another class entirely.
Hello? I thought Java didn't support multiple inheritance but here it is!
Have a look at this sample code and tell me what's going on here:
//inners2.java
class inners2
{
void printMessage()
{
System.out.println("ladida");
}
public static void main(String[] args)
{
new outerclass01().new sucker().printMessage();
}
}
class outerclass01
{
void printMessage()
{
System.out.println("humdeedum");
}
class sucker extends inners2
{}
}
So there you go, what's the above code going to print when run? Is it
"ladida" or "humdeedum"?
From seeing this I get the feeling that not a lot of thought got put into
defining what it was exactly that inner classes were supposed to do. Anybody
know what the story is here?
Thanks,
Ben.