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
问题:
回答1:
Closures are poor man's objects / Objects are poor man's closure
Please see: closures and objects
For the lazy:
The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
—Anton van Straaten
回答2:
A closure
and a class
are two very different things.
It is not correct to say 'A class
is more powerful that a closure
.' or vise a versa.
They do totally different things.
A closure
is in a basic sense, a function call that retains the local variable information from the scope it was created.
A class
is a definition of an object. The class defines behavior and the contents of instances of the class.
回答3:
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:
- The AII method has stronger type checking than a closure. (Closure systems can be made to have stronger type checking, but in general, they aren't)
- The closure syntax requires less typing. This seems to be the main gripe that renders out once you chew on the Java need closures arguments long enough.
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);}}
回答4:
I'm not sure what led you to this question, but something you've been told or something you read has severely misled you.
Ignoring language altogether, a closure and a class are completely unrelated structures/conventions in programming.
回答5:
This is a good question but could be better worded:
"What are some similarities and differences between Java objects and JavaScript closures"?
Similarities: they both have persistent state in their local variables. Their methods have access to those state variables.
Differences: Javascript is a functional language, therefore functions within functions can be immediately invoked and returned. For example:
newXY = function(x,y) {
var that = {};//Instantiate new object
var x = parseFloat(x);
var y = parseFloat(y);
that.xtimesy = function() {
return x*y;
}(); // <-- Notice the immediate invocation of the function, here.
return that;
};
So you can write code like this snippet copy / pasted from rhino shell:
js> var foo = newXY(2,5);
js> foo.xtimesy;
10