• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Inner Classes when to use them?

 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HF Java 2nd edition by Kathy Sierra and Bert Bates has a BeatBox client program in it that uses a lot of inner classes. I'm a novice so I was hoping Bert or someone else could explain if it's normal to have that many inner classes, even in a GUI class?

All but one of them are listeners so I know it makes sense for them to be classes but could you have them as their own class rather then an inner class? Same for the Runnable inner class, couldn't that be it's own class?

I guess I'm just confused because up to this point everything I've read has told me that a class should do one thing and one thing well and that is it. But now I'm getting into Threads and GUIs and it appears that one class is doing many things.

Thanks in advance,
Greg
[ October 12, 2007: Message edited by: Greg L Tonn ]
 
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Inner classes make sense when they are tiny and don't need names. Listeners in GUIs are classic examples where they make sense.

If the class is big and important, it should be named and placed in a separate file.

The listener classes in normal GUI examples do one tiny thing, usually just dispatch to some other function to do real work
 
Ranch Hand
Posts: 510
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Pat. With the exception of anonymous inner classes for event listeners i cannot think of any instance that inner classes make sense. Better to create helper classes that can be delegated to to do the work and are reusable than to create inner classes whose behavior is specifically tied to the outer class.
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the inner class needs access to private fields of the outer class, moving the inner class to its own file means making the private fields more visible, although default package visibility would suffice if you keep the moved inner class in the same package.

If you really want to keep the fields private, there is no other option than to keep the inner class an inner class.
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The inner class can hide the implement you do in the superclass!
 
Michael Ku
Ranch Hand
Posts: 510
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The use of inner classes break the OO principle of cohesion which is more important than keeping your properties private. They also do not promote reuse. Create some getters for your properties (which would make the class compliant with the bean spec :-))
 
Ranch Hand
Posts: 418
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So,just to conclude:
1.Inner classes exist mainly for listeners in the form of anonymous inner classes.
2.We should try to reduce the use of inner classes as much as possible.

Please correct me in simple words,if something else can be added.
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was under the same impression but the example in the HF Java book does otherwise. It uses named inner classes for the listeners and a named inner class for the Runnable. Using named inner classes versus anonymous inner classes may not be that big of a deal.

I was just looking to see if this was a normal example or a anomaly.

Thanks
 
Michael Ku
Ranch Hand
Posts: 510
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In my experience, except for very old code and Swing/AWT event driven applications, I have never come across any situation where using an inner class seemed like a good idea.

The books always give examples because it is still a part of the language spec and needs to be supported for older code.
 
Greg L Tonn
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Michael, what is the more typical style for Swing then, in you experience? I'm new to swing so I'm just trying to get it right!

Thanks
 
Michael Ku
Ranch Hand
Posts: 510
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have not done a lot of Swing lately. You should post that question in the Swing/AWT forum
 
Wanderer
Posts: 18671
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think this is overstating the case against inner classes. It's true that inner classes are never necessary - you can always find another way to code something using only named top-level classes. But they can often be convenient. I frequently use anonymous classes for small, simple things such as event listener. But I also often use static nested classes (which are technically not inner classes) for classes which are only used in the context of another class - Map.Entry is a good example of this. It's only used in conjunction with a Map, so having the definition of Entry be a part of the Map interface makes organizational sense.

I don't generally have much use for other types of nested classes, like nonstatic member classes and local classes. But they do occasionally come in useful. For a good example of a legitimate use for member classes, see the source code for LinkedList.ListItr. This is a private inner class whose purpose is to provide an implementation of ListIterator for a LinkedList. To do this, it's useful to have access to the private data inside the LinkedList. To achieve this using only top-level classes, it would have been necessary to expose more public methods in LinkedList to allow the ListIterator to get at the underlying implementation of the LinkedList. Instead, using an inner class allows LinkedList to keep its implementation private, as it should be.
 
Michael Ku
Ranch Hand
Posts: 510
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is a good example. In fact, the only good examples of proper use of inner classes (outside of listeners) seems to be in the core Java language. The people that write the language know what they are doing. Every other attempt I have seen to use inner classes have be butchered and difficult to work with.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So, you're saying that if anyone writes code that resembles the core libraries, like a custom Collection implementation, that code is crap all of a sudden? Just because that person didn't write the language and so didn't know what they were doing?

Here's a little secret for you: quote some code of the core libraries is crap itself. Yes you've read it right - I called core library code crap. Classes still using Vectors and not accepting any other Collection or List. Internally stored in Vectors, that are also declared as Vectors. Of course, most of these Vector fields come from a time when the Collections framework didn't exist yet, and because they are protected you can't just change the declaration, but that doesn't mean it's not crap. You don't believe me? Look at javax.swing.table.DefaultTableModel. And speaking of unnecessary nested classes, look at javax.swing.JSpinner. There are no less than four public nested classes, all of which could have (and according to several people in this discussion, should have) been separate classes. I mean, SpinnerModel is a toplevel interface, so why not these editors?

Of course there is a lot of goodness there as well, but sometimes there are some real WTFs in there.
 
Michael Ku
Ranch Hand
Posts: 510
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rob, your personal and misdirected anger has caused (for me) this thread to take an ugly turn. I was trying to complement some code that it was pointed out was well written and appropriate. I no longer have any interest in participating in this discussion.

It's all yours....
 
Ranch Hand
Posts: 101
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
While inner classes may be convenient and I'm sure a compelling argument could be made in certain situations, they are an anomaly and should be used very sparingly. The reason doesn't have anything to do with their value, convenience, or OO design IMO - it's more about doing things that will add or decrease the value of your design. If something is clear and easy to understand, it's almost always better than being more convenient.

Now, inner classes aren't exactly complex and/or hard to follow, but the sheer irregularity of encountering them force the programmer to spend a few more moments examining the code just to make sure they didn't miss something, and attempt to figure out why the previous programmer made the choice to use an inner class.

That said, if there's a really great reason - go for it, but otherwise it's most likely a poor choice. In our industry, think team - your limits are defined by your weakest programmer.
 
Greenhorn
Posts: 6
Eclipse IDE Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I conform to Pat.Believe it or not, there are advantages to Java's inner classes. But before we go into that, I'll provide a short background on inner classes.

Inner classes nest within other classes. A normal class is a direct member of a package, a top-level class. Inner classes, which became available with Java 1.1, come in four flavors:

Static member classes
Member classes
Local classes
Anonymous classes


An Inner class is a nested one, either it may be defined inside a class or inside a method, sometimes, can be anonymously.

Inner classes allow us to achieve more encapsulation and thus more security.

1.Member Class
----------------
Here, Inner class is termed as Member class.

class Outer
{
class Inner
{

}
}

*Creating the object of Inner class needs an object of outer class.

new Outer().new Inner();

To hold the object of the Inner class, the reference must be of the form,

Outer.Inner obj;


Finally,

Outer.Inner obj=new Outer().new Inner();

We can have either way,

Outer out=new Outer();
Outer.Inner obj=out.new Inner();


*An Inner class can have access to Outer class members, but the reverse is not true.

*An Inner class is just like a member of a class, and allowed all the modifiers like public,private,protected,default,static,final,abstract etc.



2.Static Inner Class
=====================

* Creation of an object of the Static Inner class doesn’t require an Outer class object, just requires the name of the Outer class.

new Outer.StaticInner();

To hold the object of the Inner class, the reference must be of the form,

Outer.StaticInner obj;


Finally,

Outer.StaticInner obj=new Outer.StaticInner();

No other way.


3.Local Inner Class
=====================

A class defined inside the body of a method.

It’s like local member of a method, can’t have access specifiers like public,private,protected.

Can have only final,abstract.

We can directly execute the Local Inner class by calling the enclosing function.

If we want any method written inside the Local Inner class, we’ll call that method, using an object created to that Local class, in the enclosing function.

We can’t have static data inside the Local Inner class.

We can’t access a non-final variable (of the enclosing function) inside a Local Inner class method.



Example:
--------

//A Static Inner class Example
class Outer
{
void enclosingFun()
{
System.out.println("Hello Outer fun");

class Local
{

void localFun()
{
System.out.println("I'm Local");
}

}
Local l=new Local();
l.localFun();
}
static class StaticInner
{
void display()
{
System.out.println("Hello Static Inner fun");

}

}

}

public class LocalInnerDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

Outer o=new Outer3();
o.enclosingFun();

}
}

4. Anonymous class
==================

A class defined inside the body of a method; and is of no name.

Example
========
//A Static Inner class Example
class Outer4
{
void display()
{
System.out.println("Displayed in Outer class");

}


}

public class AnonymousDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

Outer4 o=new Outer4(){

void display()
{

System.out.println("Displayed in Anonymous class");
super.display();
}

};

o.display();

}

}
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aryan Venkat wrote:I conform to Pat.Believe it or not...


Not a bad summary. However, I suspect Elvis has left the building. (Look at the date of the post).

Winston
 
Aryan Venkat
Greenhorn
Posts: 6
Eclipse IDE Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh I understood Mr. Winston,but I feel I was not up to the mark, can you please offer me any REAL-TIME scenario with an instance, that illustrates why use inner classes much?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aryan Venkat wrote:Oh I understood Mr. Winston,but I feel I was not up to the mark, can you please offer me any REAL-TIME scenario with an instance, that illustrates why use inner classes much?


Well, to be honest I don't use inner classes very often. I do use static nested classes a lot though.

One use for an inner class is to provide a different "view" of its outer class, and a good example is with Map implementations: the entrySet(), keySet() and values() methods use inner classes to provide the content of the Map in different flavours.

Winston
 
Aryan Venkat
Greenhorn
Posts: 6
Eclipse IDE Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Winston , but I just want dig deeper, any inner class, either it may be a member class or static nested or local/anonymous anything, but I need why and in which cases we've to opt for Inner classes, apart from the usage, they provide more encapsulation and security...Help me please.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aryan Venkat wrote:Thank you Winston , but I just want dig deeper, any inner class, either it may be a member class or static nested or local/anonymous anything, but I need why and in which cases we've to opt for Inner classes, apart from the usage, they provide more encapsulation and security...Help me please.


This is a forum Aryan, not a university class. I've provided you with one example, and here's another.

It would take too long to explain all the why's and when's (not to mention 'when not's') of inner class usage, so I suggest you look at the tutorials or get a good book on the subject.

Winston
 
Aryan Venkat
Greenhorn
Posts: 6
Eclipse IDE Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Winston,Sorry Sorry Winston , if I hurt you in any way; I'm just in a feel and hurry to learn more as java greenhorn, I feel I need the help of experts like you. It's just that.

Finally, thanks a lot for your time and interest, thanks for everything. you don't need to reply for this.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aryan Venkat wrote:@Winston,Sorry Sorry Winston , if I hurt you in any way; I'm just in a feel and hurry to learn more as java greenhorn, I feel I need the help of experts like you. It's just that.


NoNeedToSaySorry (←click) - we were all where you are once. Just remember that we're all volunteers here.

I also strongly urge you to read this page; it's a great reminder that you can't learn everything at once.

Winston
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:we were all where you are once.


Quoted for a wisdom.
 
Aryan Venkat
Greenhorn
Posts: 6
Eclipse IDE Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much for your awesome reference, I'll be grateful to you and I just wish to see me myself like you, may be after any long time, even decades and decades, I'll try hard to achieve that knowledge. I feel it's a great day for me today, I'll start with 'that' end (capability) in my mind, now with a little knowledge.
 
Ranch Hand
Posts: 300
Eclipse IDE Firefox Browser Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I personally refer JDK whenever in doubt. if you look at Map.Entry then you realize that Entry is only usable along with Map and that's why its a nested class. you can also refer Effective Java by Joshua Bloach which has one Item on inner class, which effectively says that if a class is only usable in context of Outer class than making it inner or nested make sense.
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:Well, to be honest I don't use inner classes very often. I do use static nested classes a lot though.



I use anonymous inner classes quite frequently. Basically where I would be using a closure in some other language, I'm using an anonymous inner class in Java.

Example: I wrote some code which implements undo and redo for a variety of changes. Basically the way to do that is to add an "edit" to a list of edits whenever the user makes some undoable change. (This is all in the javax.swing.undo package.) And what's the function of an "edit"? Well, whenever the user asks it to undo the change, it should set things back the way they were before the change, and whenever the user asks to redo, it should set them to the way they were after the change.

So the undo and redo actions are different for every single edit, because they act on different objects and do different things to them. So they need code which says what should be done, and that code refers to objects which are not part of the edit itself. And so you have anonymous inner classes to implement that code.

Of course you don't have to do it that way. You could write different "edit" subclasses for every possible different kind of change in the system, with suitable setters to pass in references to the things which undo and redo have to affect. But I prefer to write one undo-redo class and plug in the appropriate closures (sorry, anonymous inner class instances) as required. It's a matter of taste, really.
 
reply
    Bookmark Topic Watch Topic
  • New Topic