Can someone explain this Java syntax to me? - java

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

What kind of declaration is this? [duplicate]

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.

How come not implementing some Methods are allowed in WindowAdapter?

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)

Clarification needed on Concept of a listener anonymous class in java

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.

Java initializing abstract classes

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.

Is this code instantiating or extending an abstract class without creating a new class?

I'm fairly new to programming but I've taken the Intro CS class at my school, so I understand most of the basics (or thought I did). I'm trying to teach myself some OpenGL via JOGL and I came across a few lines of code that I couldn't understand. Am I missing something?
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
I checked the Javadoc, and WindowAdapter is an abstract class. So how can he be instantiating it?
Or is this even creating an instance?
It almost looks like the code extends WindowAdapter or overrides the windowClosing method, but how is that possible without writing a new class?
It almost looks like the code extends WindowAdapter or overrides the windowClosing method
This is exactly what's happening.
but how is that possible without writing a new class?
In fact, the code is creating a new (anonymous) class. It's just that the syntax is different to what you've come across so far. Take a look at the tutorial.
For a discussion of how anonymous classes are used, see How are Anonymous (inner) classes used in Java?
The Concept used is Anonymous class !! ....
Since WindowAdapter is an abstract class you cannot make it's object it but using Anonymous Class concept you can call its constructor or use the functions without assigning it to an object of it's type ..
Another way of using Abstract classes data variables and methods is to make objects of it's derived classes
In this way u can have a WindowAdpater instance passed in the parameter without any error.

Categories