Inner Classes a liability

M

Michael Rauscher

Hi xarax,
Inner classes are not a form of multiple inheritance
of implementation nor interface. The compiler creates
a hidden field that contains a reference to the outer
class instance. Whenever the inner class has a method
call or refers to field of the enclosing instance, the
hidden reference is used.

Also, you cannot assign a reference from the inner
class to a variable or field that is declared of the
outer class type.
Did I write anything else?

Bye
Michael
 
B

Ben Wilson

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!

No, you are applying the statement too broadly. You seem to have not
grasped the fact that for all intents and purposes, an inner class is a
*seperate* class from its containing class[es]. It has special access
to its containing class[es], true, but that's irrelevant. When you add
a method to an inner class you are not adding it to any containing
class, so you H&R's statement does not apply.

Mr. Bollinger: I appreciate that this may be the way Java works, but I fear
we must be interpreting the English language differently. If the main
property of an inner class is that it cannot exist without an enclosing
instance, then semantically yes I cannot grasp how anybody can claim that an
inner class can be considered "separate" from its containing class. If you
separate it from its containing class it ceases to exist and turns into a
top-level class. This "un-separateness" is a defining characteristic of what
an inner class is - it cannot exist independently and therefore is not
separate.

Before Java had inner classes, the relationship between two classes
prescribed the way method names could be reused and words like "separate"
and "unrelated" may have had a clear and distinct meaning. With the
introduction of inner classes to Java, I believe the words "separate" and
"unrelated" became obsolete. For someone (such as myself) who didn't grow up
with the jargon, (ie follow Java since 1995) the statements "an inner class
is separate from its containing class" or "an inner class is unrelated to
its containing class" simply must be refused as false. If it's acceptible to
say this in Java, fine, but it's no longer English we're speaking here.

There *must* be better terms than "related" or "not separate" to describe
the relationship between a child and a parent that makes it distinct from
the relationship between an outer and inner class. Anybody any ideas?

Would you disagree with me that the reuse of method names involves three and
not two cases, and that hiding is an alternative to overriding and
overloading?

No. Perhaps we're having another terminology problem, but the word
"extend" has specific meaning in the context of Java: the relationships
between a class and each of its superclasses. As we've been discussing,
a class can override methods inherited from any class it extends, and it
can offer overloaded versions of those methods.

I accept this. Following this line of thought would you say the reuse of
method names in a static context in two classes that share a parent/child
relationship are participating in "hiding"? Is this behaviour the same as
for the reuse of method names in two classes that share an inner/outer
relationship? (if you forget for a second that the way the hiding method
would reference the method it's hidden?)

Thanks,

Ben.
 
T

Tony Morris

Ben Wilson said:
the
same
method name with identical arguments and return type, well, it just *had* to
be overriding, right? Well, sure shows me!

No, you are applying the statement too broadly. You seem to have not
grasped the fact that for all intents and purposes, an inner class is a
*seperate* class from its containing class[es]. It has special access
to its containing class[es], true, but that's irrelevant. When you add
a method to an inner class you are not adding it to any containing
class, so you H&R's statement does not apply.

Mr. Bollinger: I appreciate that this may be the way Java works, but I fear
we must be interpreting the English language differently. If the main
property of an inner class is that it cannot exist without an enclosing
instance, then semantically yes I cannot grasp how anybody can claim that an
inner class can be considered "separate" from its containing class. If you
separate it from its containing class it ceases to exist and turns into a
top-level class. This "un-separateness" is a defining characteristic of what
an inner class is - it cannot exist independently and therefore is not
separate.

Before Java had inner classes, the relationship between two classes
prescribed the way method names could be reused and words like "separate"
and "unrelated" may have had a clear and distinct meaning. With the
introduction of inner classes to Java, I believe the words "separate" and
"unrelated" became obsolete. For someone (such as myself) who didn't grow up
with the jargon, (ie follow Java since 1995) the statements "an inner class
is separate from its containing class" or "an inner class is unrelated to
its containing class" simply must be refused as false. If it's acceptible to
say this in Java, fine, but it's no longer English we're speaking here.

There *must* be better terms than "related" or "not separate" to describe
the relationship between a child and a parent that makes it distinct from
the relationship between an outer and inner class. Anybody any ideas?

Would you disagree with me that the reuse of method names involves three and
not two cases, and that hiding is an alternative to overriding and
overloading?

No. Perhaps we're having another terminology problem, but the word
"extend" has specific meaning in the context of Java: the relationships
between a class and each of its superclasses. As we've been discussing,
a class can override methods inherited from any class it extends, and it
can offer overloaded versions of those methods.

I accept this. Following this line of thought would you say the reuse of
method names in a static context in two classes that share a parent/child
relationship are participating in "hiding"? Is this behaviour the same as
for the reuse of method names in two classes that share an inner/outer
relationship? (if you forget for a second that the way the hiding method
would reference the method it's hidden?)

Thanks,

Ben.



"Inner classes become separate from their 'containing' class when the source
file becomes bytecode.
There is no such thing as an inner class in the restricted context of Java
bytecode - that is, an inner class is separate from the outer class in this
context."

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
C

Chris Smith

Ben said:
I accept this. Following this line of thought would you say the reuse of
method names in a static context in two classes that share a parent/child
relationship are participating in "hiding"?

Yes, they certainly are, and the way it works is exactly the same.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Ben Wilson

Thanks, Chris, this is interesting.

Yeah, the books don't really explain that well, either, beyond saying it's
not "really" overriding. Anywhere else this is happening, besides static
"overriding" which isn't overriding at all and we'll now call "hiding" and
inner/outer "overriding" which isn't overriding at all and we'll now call
"hiding"?

I'm going to try to get my head around this...
 
B

Ben Wilson

"Tony Morris" <[email protected]> skrytta en bricht

"Inner classes become separate from their 'containing' class when the source
file becomes bytecode.
There is no such thing as an inner class in the restricted context of Java
bytecode - that is, an inner class is separate from the outer class in this
context."

I appreciate your reply but this don't make sense, dude. When I convert Java
into COBOL a lot of things change too, for there's no such thing as an inner
class in that restricted context either.

If the only way to get bytecode is to program in Java, and bytecode is 100%
semantically the same, and I can only define an inner class if I have an
outer instance context, according to my logic the case for the
"unrelatedness" of inner and outer classes is looking pretty weak. Anyway,
how can this be? On the disk it's "outer$inner", not "inner"; and you still
can't define it out of its context. As far as I've understood, you can't
even extend an inner class without extending the outer class at the same
time and reproducing the relationship.

It may seem pedantic but will you please define what you mean by the word
"separate". (And where are you getting this from?)
 
M

Michael Rauscher

Hi Ben,

Ben said:
Thanks, Chris, this is interesting.

Yeah, the books don't really explain that well, either, beyond saying it's
not "really" overriding. Anywhere else this is happening, besides static
"overriding" which isn't overriding at all and we'll now call "hiding" and
inner/outer "overriding" which isn't overriding at all and we'll now call
"hiding"?

I'm going to try to get my head around this...

In fact it's very simple and straightforward because it behaves like
variables.

If you declare a local variable (within a method) that has the same name
as an instance variable, the instance variable gets "hidden". You would
have to use "this." to access the instance variable:

public class Test {
private int number = 100;

public Test() {
}

public void printMessage() {
int number = 500;
System.out.println( number );
System.out.println( this.number );
}

public static final void main( String args[] ) {
Test test = new Test();
test.printMessage();
}
}

You can do the same with outer/inner classes:

public class Test {
class Inner {
public void printMessage() {
Test.this.printMessage();
}
}

private int number = 100;

public void printMessage() {
int number = 500;
System.out.println( number );
System.out.println( this.number );
}

public static final void main( String args[] ) {
new Test().new Inner().printMessage();
}
}

Bye
Michael
 
J

John C. Bollinger

Ben said:
"John C. Bollinger" <[email protected]> skrytta an bricht

[...]
No, you are applying the statement too broadly. You seem to have not
grasped the fact that for all intents and purposes, an inner class is a
*seperate* class from its containing class[es]. It has special access
to its containing class[es], true, but that's irrelevant. When you add
a method to an inner class you are not adding it to any containing
class, so you H&R's statement does not apply.


Mr. Bollinger: I appreciate that this may be the way Java works, but I fear
we must be interpreting the English language differently. If the main
property of an inner class is that it cannot exist without an enclosing
instance, then semantically yes I cannot grasp how anybody can claim that an
inner class can be considered "separate" from its containing class. If you
separate it from its containing class it ceases to exist and turns into a
top-level class. This "un-separateness" is a defining characteristic of what
an inner class is - it cannot exist independently and therefore is not
separate.

Let me put it a different way: the "innerness" of an inner class is
largely a property of Java source code, not a property of the class itself.

At the risk of introducing more confusion, let me point out that the
"nestedness" of a static nested class is _exclusively_ a property of
Java source code -- the terminology is a bit inconsistent, but these
_are_ effectively top-level classes in the way you mean. This is
relevant in that static nested classes have a representation in Java
source almost identical to that of inner classes, and have exactly the
same rules with regard to inheritance and hiding. They differ in that
they don't have access to non-static members of their containing
classes, which is natural because they're static.

Perhaps its also useful to note that one must distinguish between
classes and their instances. Every inner class instance has a very cozy
relationship with an instance of the relevant enclosing class, its
logically enclosing instance. _That_ is the fundamental defining
characteristic of an inner class. It does not, however, contradict my
assertion that the two objects' classes are logically quite distinct. I
could in fact write Java source for two top-level classes that produced
exactly the same kind of object relationships.
Before Java had inner classes, the relationship between two classes
prescribed the way method names could be reused and words like "separate"
and "unrelated" may have had a clear and distinct meaning. With the
introduction of inner classes to Java, I believe the words "separate" and
"unrelated" became obsolete. For someone (such as myself) who didn't grow up
with the jargon, (ie follow Java since 1995) the statements "an inner class
is separate from its containing class" or "an inner class is unrelated to
its containing class" simply must be refused as false. If it's acceptible to
say this in Java, fine, but it's no longer English we're speaking here.

I don't recall saying "unrelated". Inner classes are certainly related
to their containing classes. I maintain, however, that they are
fundamentally seperate classes. Whether that sits well with your sense
of English-language propriety or not is not much relevant -- it is the
mental model that puts these questions into the appropriate context.
There *must* be better terms than "related" or "not separate" to describe
the relationship between a child and a parent that makes it distinct from
the relationship between an outer and inner class. Anybody any ideas?

Children "extend" their parents -- that one's standard. As for outer
and inner classes, you apparently reject "outer" and "inner", which are
the most precise terms I know, albeit I grant that they don't go very
far in describing the applicable semantics. I agree with you that
"related" doesn't fully encompass the idea. "Not seperate" is not
appropriate.
Would you disagree with me that the reuse of method names involves three and
not two cases, and that hiding is an alternative to overriding and
overloading?

Yes, I would disagree. I don't consider an inner or static nested
class' (or its ancestor's (!)) use of the same method signature as a
method of a lexically enclosing class (thereby "hiding" the enclosing
class' method) to be "reuse". It's just "use".
I accept this. Following this line of thought would you say the reuse of
method names in a static context in two classes that share a parent/child
relationship are participating in "hiding"?

Yes, and that is the terminology that is normally used.
Is this behaviour the same as
for the reuse of method names in two classes that share an inner/outer
relationship? (if you forget for a second that the way the hiding method
would reference the method it's hidden?)

Yes.


John Bollinger
(e-mail address removed)
 
T

Tony Morris

I appreciate your reply but this don't make sense, dude.

Makes perfect sense.
When I convert Java
into COBOL a lot of things change too, for there's no such thing as an inner
class in that restricted context either.

I don't envy you.
In fact, I can't even think how one would go about doing such a nightmarish
thing (without abusing the language, which is often the case in these
"language conversion" tasks).
(And where are you getting this from?)

Java Virtual Machine Specification Second Edition
Java Language Specification Second Edition

Apologies for the brevity - I'm sure you'll figure it out.

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
B

Bent C Dalager

I still disagree with the terminology here.

You should think of the ability of an inner class to call methods of its
outer class as a convenience offered to you by the compiler, and nothing
more.

I agree. I think of it as short-hand for "OuterClass.this." provided
by a (perhaps overly helpful) compiler.

When I write something like
class A
{
void printSomething() { System.out.println("something"); }

class B
{
void do() { printSomething() }
}
}

then the call to "printSomething()" is really just short-hand for
"A.this.printSomething()".

It has nothing to do with inheritance, it reminds me more of
precompiling even if resolving this requires more information than is
normally available to a precompiler.

It _does_ seem strangely similar to static imports in 1.5 though?

Cheers
Bent D
 
R

Roedy Green

I agree. I think of it as short-hand for "OuterClass.this." provided
by a (perhaps overly helpful) compiler.

I was working an a program on the weekend where I was puzzled at error
messages. They all cleared up when I fully qualified Outerclass.this
and Outerclass.somestatic. Sometimes it seemed to me the compiler
should have been be able to tell what I meant, but it could not. I
decided then just to always qualify. Probably helps programmers too
to know where to look for the variable definitions.

Then there is that strange "final" rule.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top