Date: | August 1, 2006 / year-entry #259 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20060801-19/?p=30273 |
Comments: | 24 |
Summary: | When you declare a class inside another class, the inner class still acts like a regular class. The nesting controls access and visibility, but not behavior. In other words, all the rules you learned about regular classes also apply to nested classes. The this keyword in an instance methods of a class (nested or not)... |
When you declare a class inside another class, the inner class still acts like a regular class. The nesting controls access and visibility, but not behavior. In other words, all the rules you learned about regular classes also apply to nested classes.
The
Java nested classes behave the same way, but Java also has
the concept of inner classes.
To construct an instance of an inner class in Java, you write
In C++ and C#, you will have to implement this effect manually. It's not hard, though:
In Java,
the inner class has a secret
The C# equivalent to this code merely makes explicit
the transformation that in Java was implicit.
We give the inner class a reference to the outer class
(here, we called it In other words, Java inner classes are syntactic sugar that is not available to C#. In C#, you have to do it manually. If you want, you can create your own sugar: class OuterClass { ... InnerClass NewInnerClass() { return new InnerClass(this); } void SomeFunction() { InnerClass i = this.NewInnerClass(); i.GetOuterString(); } }
Where you would want to write in Java
Now, I'm not saying that the Java way of representing inner classes isn't useful. It's a very nice piece of sugar if you access the outer class's members frequently from the inner class. However, it's not the type of transformation that makes you say, "Well, if a language doesn't support this, it's too hard for me to implement it manually, so I'll just give up." The conversion is not that complicated and consists entirely of local changes that can be performed without requiring a lot of thought. As a postscript, my colleague Eric Lippert points out that JScript.NET does have instance-bound inner classes. class Outer { var s; class Inner { function GetOuterString() { return s; } } } var o = new Outer(); o.s = "hi"; var i = new o.Inner(); i.GetOuterString(); |
Comments (24)
Comments are closed. |
This is cruel.
Most java evangelists tell to their believers that C# has too much syntactic sugar. :D.
IIRC Java actually supports both types. If you declare your inner class with the static keyword then it will not have any access to the outer class. This saves the implicit reference being added by the compiler.
Inner classes were a necessity in Java due to the event model, your inner class could implement IFocusListener (or whatever) and access the private members of the outer class to perform some action on the event.
Tom’s technically right. Inner classes were accidentily left out of the list of members that could access the (outer) classes private parts.
I’m not sure any compiler actually enforced that rule, and e.g. VC2005 certainly doesn’t. So in practice this restriction doesn’t matter.
"In C++, your friends can see your privates"
The (bizarre) Java syntax for instantiating an inner class is actually:
this.new InnerClass();
The Java syntax is sligthly off, it’s "object.new InnerClass()".
In 98% of cases the object is ‘this’, and you can just use "new InnerClass()".
I suspect the reason this is in Java and not in C# is because C# has delegates, whereas Java must rely on inner classes (specifially, "anonymous inner classes").
I agree with JavaSharp’s statement. The primary reason that inner classes are useful in Java is the lack of delegates.
Also, it’s interesting to note the awful syntax when you want to do an explicit reference from an inner class method to a containing class member:
Outerclass.this.s = "foo";
Ugh.
However, it can be necessary when the inner class has a member with the same name as the outer class, and one needs to access the outer class method from the inner class.
But are not delegates just syntactic sugar?
http://java.sun.com/docs/white/delegates.html
“We believe bound method references are unnecessary because another design alternative, inner classes, provides equal or superior functionality…”
“We believe bound method references are harmful because they detract from the simplicity of the Java programming language….”
AC: Yes, but it’s not the type of transformation that makes you say, "Well, if a language doesn’t support this, it’s too hard for me to implement it manually, so I’ll just give up."
:-)
I’m glad to see that the inner C# class has access to the outer class’s private members. The current C++ standard does not allow that type of access without a friend declaration. If memory serves, Pete Becker in a recent issue of Dr. Dobb’s Journal (I miss you CUJ! *sniff* ) made mention that the latest C++ draft standard will allow for C#-like access semantics. [Note: After searching hard for verification on the C++ Committe Website, I have been unable to corroborate my own statement; it may, in fact, be totally wrong!]
"Java inner classes are syntactic sugar"
True: in the exact same way that non-virtual instance methods are syntactic sugar over static methods ;-)
"Not actually a .Net blog"
PingBack from http://jaysonknight.com/blog/archive/2006/08/01/Working-On-Some-CSModules.aspx
lack of delegates aren’t the reason for inner classes in java.
inner classes are useful for hashmap nodes, enumerators, and any other object who’s existence is based in the life of the parent object.
any particular reason you chose to refer to third party spec instead of official Sun’s spec?
You’ve got a bad google-fu (http://ask.metafilter.com/mefi/21557), Raymond :P
First hit for this search: http://www.google.no/search?q=java+language+specification
.. is http://java.sun.com/docs/books/jls/ :)
Similar with MSN Search, btw.
Is there a reason the Java-like behaviour wasn’t adopted? After
all, Java does support both methods, it wouldn’t have been hard for C#
to do the same thing.
Why not get rid of the syntactic sugar that allows you to write i.GetOuterString() and write Outer_Inner_GetOuterString(i) instead ;-)
There’s been a lot of debates out there recently about how useful is the method reference (or function pointer) in programming or scripting languages such as JavaScript, C# and J++. It looks like Java turns out to be the loser in this debate because it
PingBack from http://www.alternateinterior.com/?p=47
PingBack from http://dotnet.robertmao.com/2007/11/17/c-nested-classes-vs-java/