Can someone explain this Java syntax to me?
What are those brackets doing inside the outer parentheses?
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
It's called an anonymous inner class. It creates an unnamed class that extends WindowAdapter (it would also have been possible to specify an interface, in which case the class would implement that interface), and creates one instance of that class. Inside the brackets, you must implement all abstract methods or all interface methods, and you can override methods too.
This is an anonymous inner class -- the brackets denote the beginning and ending of the class declaration. This is a potentially useful SO question, and a bunch of others.
And to complement andersoj's answer, you usually use them when a method expects an instance of X, but X is an abstract class or an interface.
Here, you're actually creating a derived class from WindowAdapter, and overriding one of the methods to do a specific task.
This syntax is very common for event handlers / listeners.
It is an anonymous inner class. It is just a shortcut. You can imagine how the code would look like if you needed to create it as a top level class:
class CloseApplicationWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Then, inside your code you would do:
CloseApplicationWindowAdapter adapter = new CloseApplicationWindowAdapter();
addWindowListener(adapter);
Both solutions have exactly the same effect (althoug the anonymous class would create a Class$1.class file, for instance). Java programmers will often prefer the anonymous class approach if the anonymous class does not get too big/complicated/important.
Related
The WindowAdapter class of Java is defined as an abstract class and has many abstract Methods, including:
windowClosing()
windowClosed()
windowActivated()
All of these methods are empty and Java says the class exists as a convenience for those who do not want to create classes implementing WindowListener. Because unlike the WindowListener Interface, WindowAdapter gives us the choice to implement only one of the abstract methods defined in it.
For example if I add the below code to a class that inherits from Window, I make the window closeable through the 'x' button on the upper right corner:
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
dispose();
}
});
However this confuses me. First of all what exactly is happening here? Am I creating an inner class that extends WindowAdapter? The new keyword is normally used to create an instance, but obviously I am not allowed to instantiate an abstract class. So why the new keyword here?
Second, why do I get away with implementing only one of the abstract methods in WindowAdapter?
Normally in Java if I define an abstract class:
public abstract class UpperClassAb {
public abstract void test();
public abstract int boa();
}
and then try to use this class, just like I have used the WindowAdapterabove:
UpperClassAb tester = new UpperClassAb() {
public void test() {
System.out.println("mor");
}
};
I get an error, because I am not implementing all the abstract methods but only one of them. How can I get away with implementing just one of the abstract methods in the case of WindowAdapter? Is this a single case, and if not can I imitate this behavior?
Although WindowAdapter is an abstract class, its methods are not abstract but empty. So you do not have to implement them, but you can override them if you want.
https://docs.oracle.com/javase/7/docs/api/java/awt/event/WindowAdapter.html
Regarding the new keyword: this is called an anonymous class. You basically create a new class without a name, and instantiate it at the same time. So the new class does not have a name, it extends WindowAdapter, overrides one method, and can ONLY be instantiated at this location (because it has no name)
If you are trying to implement WindowListener, you should provide implementation for all the methods. Here window adapter is nothing but the abstract class which provides partial implementations for the window events. Because of this you can provide the implementation for the particular event(e.g windowclose)
I'm new to java. What is the purpose of a listener anonymous inner class design? I heard that anonymous classes are used as listeners in java. And that no one really creates inner classes or even static inner classes. I'm not sure what that means. could some one explain these concepts a bit? Especially this listener design and how its created via an anonymous class.
Thank you in advance.
An anonymous listener would usually look something like this:
myControl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Handle event
}
});
Using an inner class to accomplish the same goal would usually look something like this:
public void init()
{
myControl.addActionListener(new MyActionListener());
}
private class MyActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// Handle event
}
}
Now consider what the two would look like in the scope of a much larger program. The anonymous listener is still right there at the spot where you're adding it. The inner class may be somewhere else in the source file entirely. With a good IDE, that difference can be minimized (such as a members browser), but is there really a need for an entirely new class for something you're going to use once?
Of course, depending on the exact needs of your application, a separate class might in fact be a better choice. If, for example, you have many listeners that differ only a little bit, you could construct something along these lines:
public void init()
{
myControl1.addActionListener(new MyActionListener("foo"));
myControl2.addActionListener(new MyActionListener("bar"));
myControl3.addActionListener(new MyActionListener("baz"));
}
private class MyActionListener implements ActionListener
{
private String word;
public MyActionListener(String word)
{
this.word = word;
}
public void actionPerformed(ActionEvent e)
{
// Handle event
System.out.println(word);
}
}
As far as static classes go: in Java, an inner class can be marked static, and all this does is prevent it from having a reference to the instance of the enclosing class. (For example, MyProgram.MyStaticClass would not be able to access any members of MyProgram which weren't static, unless it creates a new instance of MyProgram.) This may help with separation-of-concerns, but doesn't change very much when it comes to listeners.
That's not true, that no one creates named classes to handle events. Yet most of the time event handlers actually are anonymous classes. The reason for that is that anonymous classes offer less code and less files to maintain and it's easier to read a code when you don't have to jump between many small files. Anonymous classes shouldn't be too long (i.e. no more than ~20 lines of code), if they are longer, they should be converted to named classes. Anonymous classes are common in java version less than 8. In java 8 there are Lambda expressions, which are similar to anonymous classes, but they are more compact.
In languages with support for first class functions listeners can be implemented like this:
def myFunction() { //code }
button.onClick(myFunction)
for simplicity some languages has the capability to define anonymous functions (aka lambdas):
button.onClick({ // code})
Are called "anonymous" because don't need a name to reference it, are used in place.
Java don't has first class functions, instead the listener pattern is implemented with a class that implement some interface:
class myListener implements ButtonListener {
public void listen(...);
}
button.onClick(myListener)
Analogous to the anonymous functions, for simplicity, java has the concept of anonymous classes, you can do:
button.onClick(new ButtonListener {
public void listen(..) { //code }
});
Note: this are simple "ilustrative" examples with an invented on the fly api :P
In java 8 first class functions (closures) are introduced, a huge and very good addition to java IMMO.
Inner classes: sometimes is good that one class is defined within the scope of another class, not the most useful java property IMMO, i use occasionally but can live without it in other languages.
Can someone explain this line of code for me?
SomeAbstractClass variable = new SomeAbstractClass() { };
This properly instantiaties and stores the abstract instance in the variable. What is happening? An anonymous class that extends the abstract class, maybe? Any keywords I can use to look up information about this? (the abstract class also happens to be generic if that has any relevance)
The line above is creating an anonymous subclass of SomeAbstractClass, which will not be abstract. Of course, this will work only if the base class has no abstract methods to implement.
Actually, I cannot visualize an useful instance (besides "documentation" features, see the comment below) of the line above, unless you are implementing and/or overriding methods between curly braces. That is a quite common technique if the base class/interface happens to have few methods to implement and the implementation is simple. You can even refer to the final variables of the surrounding method and parameters, thus making a closure.
You are creating an anonymous class which is a subclass of your abstract class. Like was pointed out in comments, you are looking at an anonymous extends.
Something like follows would work if you had abstract methods to implement:
MyAbstractClass someObjectOfThatClass = new MyAbstractClass(){
#Override
public void someAbstractMethod(){
}
}
You can do the same with interfaces as they can also contain abstract methods. A practical example would be adding an ActionListener to a JButton:
myJButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
// code
}
});
Java gives you the ability to create anonymous subclasses inline. You often see this in the context of anonymous inner classes with Swing event handling, but there are many other applications as well.
In your example, you are creating a class that extends SomeAbstractClass anonymously and assigning it to a SomeAbstractClass reference. It would be just as if you created a separate class like this
public class SomeConcreteClass extends SomeAbstractClass {
}
and later did this
SomeAbstractClass variable = new SomeConcreteClass();
As noted by #Stefano, your approach only works if your anonymous concrete class has no abstract methods, which would be true because SomeAbstractClass has no abstract methods.
What I was told, which sparked my curiosity on this topic:
Java gui classes can implement hundreds of Listeners and Callbacks and many books teach you to implement all these interfaces in your gui class. Alternatively, these aspects can be implemented in inner classes, so methods called by that listeners do not get mixed up.
I'd like to know how to do this in ActionScript, which doesn't have inner classes, but has private classes. But, I don't think I fully realize what inner classes are about, so I'm merely trying to wrap my head around the situation where I would use them to organize a class' methods by their usages.
Please show an example of how this would look in ActionScript, if possible, otherwise Java.
In java it looks like that:
new JButton().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// code that will be performed on any action on this component
}
};
here ActionListener - is an interface, and by calling new ActionListener() {/*interfaces method implementations goes here*/}; you're creating anonymous class (anonymous because it has no name) - implementation of that interface.
Or you can make inner class like this:
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// code that will be performed on any action on this component
}
};
and then use it like this:
new JButton().addActionListener(new MyActionListener());
Moreover you can declare your listener as a top-level or static inner class. But using anonymous inner class sometimes is very useful because it allows you to implement your listener almost in the same place where the component which actions your listener is listening to is declared. Obviously it won't be a good idea if the listeners methods code is very long. Then it would be better to move it into a non-anonymous inner or static nested or top-level class.
In general, innner classes are non-static classes that somehow resides inside the body of the top-level class. Here you can see examples of them in Java:
//File TopClass.java
class TopClass {
class InnerClass {
}
static class StaticNestedClass {
}
interface Fooable {
}
public void foo() {
new Fooable(){}; //anonymous class
class LocalClass {
}
}
public static void main(String... args) {
new TopClass();
}
}
Gasan gives an excellent example of how inner classes are typically used for callbacks in Java GUIs. But in AS3 you would not normally do it this way, because AS3 event listeners are function references, not interfaces. In this respect, AS3 has more in common with JavaScript than Java.
What you can do in AS3 (just as with JavaScript) in place of the anonymous inner class callbacks is create function closures.
EDIT: I found a reference here that saves me a lot of typing:
ActionScript 3.0 using closures for event handlers
Can someone explain this Java syntax to me?
What are those brackets doing inside the outer parentheses?
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
It's called an anonymous inner class. It creates an unnamed class that extends WindowAdapter (it would also have been possible to specify an interface, in which case the class would implement that interface), and creates one instance of that class. Inside the brackets, you must implement all abstract methods or all interface methods, and you can override methods too.
This is an anonymous inner class -- the brackets denote the beginning and ending of the class declaration. This is a potentially useful SO question, and a bunch of others.
And to complement andersoj's answer, you usually use them when a method expects an instance of X, but X is an abstract class or an interface.
Here, you're actually creating a derived class from WindowAdapter, and overriding one of the methods to do a specific task.
This syntax is very common for event handlers / listeners.
It is an anonymous inner class. It is just a shortcut. You can imagine how the code would look like if you needed to create it as a top level class:
class CloseApplicationWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Then, inside your code you would do:
CloseApplicationWindowAdapter adapter = new CloseApplicationWindowAdapter();
addWindowListener(adapter);
Both solutions have exactly the same effect (althoug the anonymous class would create a Class$1.class file, for instance). Java programmers will often prefer the anonymous class approach if the anonymous class does not get too big/complicated/important.