Thursday, February 28, 2008

I wish languageXYZ had inner classes....

I've been in love with inner classes since I first encountered them in the first java course I attended.

I remember we had an exercise to build a text chat client and one thing we had to do was handle a case where a button behaved differently depending on which state it was in. I proceeded to create two different listeners and removed the one and added the other each time the state changed. This surprised the teacher who had never seen any other solution than a simple if-then-else in the one listener (a solution that didn't even enter my head, strangely enough). Perhaps I was going overboard but it just seemed so much tidier.

The book we got was "Thinking in Java" and, needless to say, I feasted on the chapter about inner classes (greenhouse controls was the example used there) and the realization that the (non-static) inner class lives in the environment formed by the surrounding object. Really cool, I didn't have to pass all state as parameters any more.

And an inner class can extend the class it resides in, there's great potential there. I was quite taken by the beauty of the hypergeometric probability calculator I wrote up to calculate the probability of a bridge player holding a specific pattern of cards:

public class HypergeometricProbability {
private class SpecificCard extends HypergeometricProbability {
...
}
...
public HypergeometricProbability andHoldsSpecificCard(int ofRemainingCards) {
/* I wish I knew how to get a reference to the surrounding object without having to pass "this" explicitly. */
return new SpecificCard(ofRemainingCards, this);
}
...
}

And then you have anonymous classes that can capture state from the method invocation they're declared in. I must confess I generally don't use anonymous classes, I find it usually much neater and more readable to create a named private inner class with a proper constructor encapsulating the needed state.

Another cool thing in java that I'm still playing with finding the full potential of is java enums. How great is it that they're actual classes that can implement interfaces, extend classes and completely encapsulate all things about the state they represent?

When researching for my previous blog entry, I came across a blog entry by Daniel Spiewak, Magic closure syntax. This roused my curiosity and got me thinking "Can it be that java is different enough that you have to find the java way of doing things? This won't be exactly like you're used to doing it with your favourite abstraction from languageXYZ, but will it necessarily be less elegant?" I hope to be able to explore this question further in following blog entries and you're welcome to provide me with challenges.

2 comments:

Daniel Spiewak said...

The only problem with avoiding anonymous inner classes is you then have some very verbose code to deal with common scenarios like event listeners. Optimally, events would be handled using closures, but since Java doesn't have those, anonymous inner classes are the next best thing.

tobe said...

@daniel:
Simon Morris basically punctures the thought that closures are much less verbose for event listeners, http://weblogs.java.net/blog/javakiddy/archive/2008/02/evolution_vs_in.html . Using a named inner class to encapsulate all that logic would to my mind be much more readable.