views:

1055

answers:

11

I have a class, let's call it LineGraph, that renders a line graph. I need to subclass it, but the derived class is only used in one place and is coupled to the class that uses it. So I am using an inner class.

I see two ways to do this:

Anonymous inner class

public class Gui {
    LineGraph graph = new LineGraph() {
        // extra functionality here.
    };
}

Named inner class

public class Gui {
    MyLineGraph graph = new MyLineGraph();

    private class MyLineGraph extends LineGraph {
        // extra functionality here.
    }
}

I am not a fan of anonymous inner classes, because frankly I just think it looks really ugly. But in the case of a subclass that's only used in one place, is a named inner class overkill? What is the accepted practice?

+4  A: 

Why do you need to subclass it? If it's just to override an existing virtual method, I think an anonymous inner class is okay. If you're adding extra functionality, I'd use a named class. I'd make it a nested class though (i.e. with the static modifier) - I find them easier to reason about :)

Jon Skeet
My example was somewhat simplified. In the real code, it overrides 5 (non-abstract) methods.
Joe Attardi
That sounds like enough to make it worth making into a named class. I like my anonymous classes to be small.
Jon Skeet
agreed. I generally only use anonymous classes if they're really simple. Any more than one small function definition and I'll make it a normal inner class (static if possible). Just easier to read that way.
Herms
Looks like you should not use inheritance but make LineGraph an interface and use a different implementation (maybe delegating to your now base class).
Jacek Szymański
A: 

I think what you've done makes perfect sense in this case and either way you look at it, I think you are really splitting hairs with this particular issue. They are both so similar and either will work.

Mike Pone
There are plenty of times where two options will work but one is more readable and maintainable than another. I think it makes a lot of sense to ask for other people's opinions when in doubt about the best way to go.
Jon Skeet
+16  A: 

One advantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can protect an inner class from being accidentally used elsewhere.

Also, using the anonymous inner class gives anyone reading your code a head's up - "this class is being used just here and nowhere else." If you see a named inner class, someone might think it'd be used in multiple places in the class.

They are very similar, so neither point is a game-changer. I just think it helps for clarity if you use anonymous inner classes for one-offs, and named inner classes when it's used multiple times within the class.

Daniel Lew
+1 Good points, but remember classes can be defined inside functions, too. This limits their scope and can be a good hint they they have a very localized use.
Outlaw Programmer
These are very good reasons not to use anonymous classes. :)
Jacek Szymański
A: 

I think this is a matter of taste. I prefer to use anonymous classes for Functors. But in your case, I'd use an inner class, since I think you'll be packing more than just a few lines of code in there, perhaps more than just a method. And it would emphasise the fact that it's adding functionality to the superclass, by putting it inside the class, rather than hidden somewhere in a method. Plus, who knows, maybe someday you might need the subclass else where. This, of course, depends on how much you know about how your software will evolve. Other than that, just flip a coin. :)

Andrei Vajna II
+2  A: 

Anonymous inner classes are hard to debug in Eclipse (thats what I use). You will not be able to look at variable values/inject values by simply right clicking.

Kapsh
+1  A: 

Anonymous inner classes would generally be the way to go. I find them very readable. However, if the instance of that class ever needs to be serialized (even if only because it's a field of something else), I would strongly recommend using named inner classes. The names of anonymous inner classes in the bytecode can change very easily, and this can break serialization.

Adam Crume
+8  A: 

(Counter point to Daniel Lew)

One disadvantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can help ensure that an inner class is not accidentally recreated elsewhere.

Also, using the anonymous inner class gives anyone reading your code a harder time as they then have to parse this class that came out of nowhere. Using a named inner class you are able to organize the source more.

I have seen cases where there are two (or more) anonymous inner classes with the exact same code. In GUIs especially (where you may have multiple controls performing the same action) this can crop up (and I am talking production code, not code that my students have written).

The readability issue goes both ways, some people find anonymous inner classes better as it lets you see what is going on in once place, others find it a distraction. That part comes down to personal preference.

Also making an class static is more efficient, if you are declaring an anonymous inner class in an instance then there will be more overhead, which, if you don't need access to the instance variables, is wasteful (but probably not worth worrying about until it presents as a problem).

My personal preference is to use non-anonymous classes as they allow for more flexibility when the code is modified later.

TofuBeer
This is what I find ugly about the anonymous inner classes. You are reading through the code, and suddenly there is this class definition smack in the middle of a bunch of fields.
Joe Attardi
I always have problem aligning the code inside anonymous class. No matter how hard I try, the code still looks ugly :D
janetsmith
+2  A: 

A disadvantage of inner classes is that they can not be static. This means that will hold a reference to the outer class that contains them.

Non-static inner classes can be an issue. For example we recently had an inner class being serialised, but the outer class was not serializeable. The hidden reference meant that the outer class would also be serialised, which of course failed, but it took a while to find out why.

Where I work, static inner classes are encouraged in our coding best practices (where possible) as they carry less hidden baggage and are leaner.

A: 

I don't have a problem with simple anonymous classes. But if it consists of more than a few lines of code or a couple of methods, an inner class is more clear. I also think that under certain conditions they should never be used. Such as when they must return data.

I have seen code where a final array of 1 item is used to pass data back from a call to an anonymous inner class. Inside the method of the anon class, the single element is set, then this 'result' extracted once the method is complete. Valid, but ugly code.

Robin
+1  A: 

Do the simplest thing that could possibly work: Use the anonymous inner class.

If you later find that you need a broader scope, then refactor the code to support this.

(You would do the same with variables -- putting them in the most specific scope. It makes sense to do the same with other source assets.)

Jeff Grigg
+1  A: 

My personal rule of thumb: If the anonymous inner class is going to be small, stick with an anonymous class. Small being defined as around 20 - 30 lines or less. If it is going to be longer, it starts to be unreadable in my opinion, so I make it a named inner class. I remember once seeing a 4000+ line anonymous inner class.

Avrom