I don\'t understand how closure is more powerful than class. It looks like I can achieve the same behavior of closure using class. Any help would be appreciated
The differences between a class and a closure have been explained by others already. I just wanted to point out that in many places in the Java API where a language that supported them would/could use closures, an anonymous implementation of an interface is used. For instance consider the code below:
JButton btn = new JButton("Say Hello");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageBox("Hello");
}
});
In this case the anonymous ActionListener could be said to be acting as a closure, if Java allowed closures, the code might look like this: (using c++0x-esque syntax)
JButton btn = new JButton("Say Hello");
btn.addActionListener([]=>(ActionEvent e){JOption.showMessageBox("Hello");});
In this trivial case, the main difference between a closure and an anonymous implementation of an interface (AII) is that:
I have yet to run into a situation where AII can't do what needs doing. Yes, there is more typing and another interface to define, but they system works and is, IMHO, more powerful since you needn't use an AII but rather can use a full-fledged class with it's own methods, member data, and constructor. An example is an action listener that pops up a context menu. If you make a class that implements ActionListener and takes a JMenu as it's argument, you can do:
btn.addActionListener( new ContextMenuActionListener(myMenu) );
This looks cleaner (to me) than a boost:bind type solution.
[]=>(ActionListener) myContextPopupClosure = []=>(ActionListener E){ ... };
...
btn.addActionListener( Closure.bind1(myContextPopupClosure,myMenu) );
or so
EDIT:
After doing a lot of work last night messing with generics, I realized one advantage of closures over AII. In the above examples, I have been assuming that the closure would be of type []=>(ActionEvent), but it really could be of the type []=>(? super ActionEvent). This means:
[]=>(Object) c = []=>(Object o) { System.exit(0); }
btn.addActionClosure( c );
window.addMouseMovedClosure( c );
//Each method in MouseMotion listener would need it's own closure.
//So I 'invented' an API change.
Would be compilable. This could prove useful, for when you need to do the same thing in response to multiple events.
Another example. This closure could be added to any place that takes a closure. If added to something as an ActionListener or MouseListener, it would log calls.
[]=>(Object ... objs) log = []=>(Object ... obj) {for(Object o:obj){logObject(o);}}