I often see people write inner classes for listeners take swing for example.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//some action
}
});
At my uni there is a lot of emphasis on designs being decoupled using design patterns such as MCV or MVP.
When would I want to use an inner class over a decoupled way of doing it?
My only guess is when objects don't need to interact? (Or laziness??)
(Student)
This is actually called an anonymous inner class. You would use it if you only need to use the class once.
It would also reduce the size of your code unless it overrides many features of course (personally I prefer anonymous classes to be small in size for readability).
This Kind of Anonymous Inner Classes are called argument-defined inner classes,and automatically instantiated as part of the method invocation.
Here in the method argument, we get an object of a class,which is the subclass of the ActionListener Interface,but the newly created class is without any name(anonymous) so we cannot create its object again after the control passes through this statement.
now in the anonymous inner class which implements ActionPerformed Interface ,we override the actionPerformed() method which is very specific to that button and then new keyword creates an object of this anonymous class and it will automatically passed as argument.
or you may also create a new class(say myListener) which extends ActionListener class and overrides its actionPerformed() method. and then create a new object of myListener and pass it to the addActionListener()method as argument.
if you use metohod 2. you can see if you have 10 buttons and each have to perform different task ,then you have to create 10 ActionPerformed implementor classes and
pass object to the addActionListener() method of these implementor classes.
It is totally foolish to use this approach to create a whole new class just for a single object.
That's why most Listener are passed as an object of anonymous inner classes.
Related
I will illustrate my issue with the use of an example:
The addActionListener method accepts an ActionListener Interface as its only argument.
So when invoking that method on an object/component (such as a Button) in order to register a listener to the object, through the use of an anonymous inner class, why is it that we also need to implement the Interface class? Is it because by definition, interfaces cannot be instantiated, unless of course you are creating an object of that Interface type that implements the abstract methods of that Interface?
i.e.
aButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do stuff
}
});
That is, through the use of anonymous classes, we can avoid explicitly making the entire class implementing the interface (as declared in the header), but rather we are instantiating an object of the Interface (which by definition of an Interface shouldn't be possible) and implementing the Interface's abstract methods within the anonymous class.
So it is only possible to instantiate an object the Interface due to the fact that at that point in time, a contract needs to be fulfilled to implement the Interface's methods, and in doing so, allows us to make an object from the Interface?
Therefore, is the reason why we can implement the actionPerformed() method of the Interface only possible because of the fact that we had instantiated an object from the Interface (which simultaneously requires us to fulfil the contract of implementing the abstract methods)? So could it be said that we are 'implicitly' implementing an interface by the in-situ instantiation of the Interface (as the addActionListener argument)?
You are not instantiating the interface.
You are defining and instantiating an actual, concrete class that implements the interface. You need to implement every method declared in the interface, just as if you wrote a "normal" class implementing the interface.
The anonymous class construct saves you the trouble of having to name a class that is only going to be used in one very specific place in your code. But if you wanted to you could have decided to do that. Under the covers it is the same thing -- you have defined a class to implement the interface and then instantiated that class.
Here's a simple case:
private final MouseAdapter mouse = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
calculate();
}
};
It's a class level field, so calling it an Anonymous Class doesn't seem right. None of the other names or descriptions in the Oracle Tutorials page on Nested Classes seemed to fit either.
I'm guessing it's something along the lines of "Single Use Object" but I'm having a hard time even describing it without saying something like "Class Level Named Anonymous Class"
For those not familiar with Java and AWT, I'm making an instance of a class that has no-operation methods to implement an interface for listening to mouse actions. I want an actual instance so I can add it as multiple types of listeners (wheel, motion, and click) but use the same object for control. The question itself is not AWT specific though.
Let's split it in pieces
private final MouseAdapter mouse is called a class member, which type (MouseAdapter) denotes that the member can refer to instances and/or sub-classes of MouseAdapter.
new MouseAdapter() { ... } is called an anonymous implementation of the MouseAdapter interface/abstract class.
So, to summarize: the class member mouse holds a reference to an anonymous implementation of the MouseAdapter interface/abstract class.
It is an instance of an anonymous class, there's no need to find a new name for this.
From Oracle docs :
Anonymous classes enable you to make your code more concise. They
enable you to declare and instantiate a class at the same time. They
are like local classes except that they do not have a name. Use them
if you need to use a local class only once.
It does not say the instance is to be used only once, but only the class, so there is no contradiction with your case.
Agree with kocko's answer but want to add one thing which is ,
Anonymous classes are expressions, which means that you define the class in another expression.
So no matter where you declare it,it will remain anonymous class and no need to name your declaration differently. :)
I’m reading an article about inner class. I found an example that demonstrates anonymous inner class (mentioned below).
button1 = new JButton();
button2 = new JButton();
...
button1.addActionListener(
new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent e)
{
// do something
}
}
);
According to the example it creates an inner class for responding to a button using ActionListener interface. As I know an interface does not have a constructor. But I’m wondering, how they call a constructor.
"new java.awt.event.ActionListener(){
}"
An interface does not have a constructor, but an anonymous class does: like all classes, it extends java.lang.Object implicitly, therefore it can call the Object's parameterless constructor.
Moreover, Object's constructor is the only constructor you could call, because anonymous classes cannot define custom constructors.
Of course in addition to extending java.lang.Object your anonymous class implements ActionListener - that's why you can pass it to the addActionListener method.
you are constructing a subclass.
Have a quick look at the Java Specification - specifically the Default Constructor Section. You get a constructor because when you instantiate an instance of an interface it would be an Object.
Quote from the spec:
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
Anonymous inner class: An inner class with no name.
Now the only detail here we care about is, this new class should subType the interface and for that we provide the necessary method implementations.
The constructor for this class is a default one and performs the job well because there are no instance variables associated.
new java.awt.event.ActionListener(){ }
This statement creates an anonymous class object that implements ActionListener interface.
That is you are invoking anonymous class default constructor not the interface one.
According to java docs
The anonymous class expression consists of the following:
1.The new operator
2.The name of an interface to implement or a class to extend.
3.Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: In the case of implementing an interface, there is no constructor, so you use an empty pair of parentheses.
How are Anonymous (inner) classes used in Java?
http://www.programmerinterview.com/index.php/java-questions/java-anonymous-class-example/
You are not instantiating an interface. You are asking the compiler to create an anonymous class implementing that interface and immediately create an instance of this class.
The best way to demonstrate this is to go to the "class" directory. You will find files of the form className$1.class, className$2.class, etc. These files correspond to those anonymous classes. If you were instantiating the interface itself, there would be no need for these new class files (and the anonymous classes they contain, of course).
That is how Anonymous Classes are(syntax wise).
According to the docs
The anonymous class expression consists of the following:
The new operator
The name of an interface to implement or a class to extend.
Parentheses that contain the arguments to a constructor, just like a
normal class instance creation expression. Note: In the case of
implementing an interface, there is no constructor, so you use an
empty pair of parentheses.
A body, which is a class declaration body. More specifically, in the
body, method declarations are allowed but statements are not.
So I've stumbled across several ways of implementing an ActionListener and I'm wondering if someone can walk me through the differences of how each works and whether there are reasons or advantages to use one over the other?
The first is below in a block of code:
public void actionPerformed(ActionEvent arg0) {
// CODE HERE
}
The second way I saw was within another block of code as:
private class myListener implements ActionListener {
// CODE HERE
}
The third was is simply having a separate class for the ActionListener, with similar code to that above, but within a separate class.
I'm wondering whether the method approach is more efficient as new objects don't have to be created for each, you simply reference this as the ActionListener rather than, for example, referencing new myListener(). Thank you.
There's no difference in speed in any of the options; you'll always have an object that implements the ActionListener interface. Avoiding an instance of a separate class will just save you a few bytes of memory.
Your choice really should be based on what makes sense for your code, structurally. For example, having your public class implement ActionListener may look weird for those who are using that class, especially if the ActionListener behavior is supposed to be private to the class and not used outside it.
So it's mostly a choice of what you think looks better in your code; the only real difference will be with regards to field / method access (e.g. a separate, non-inner class won't have access to private methods and fields of your class, an anonymous inner class can't access non-final variables of the enclosing method, etc).
I don't like or use "implements ActionListener".
I do like and use anonymous inner classes like:
btnPurplescreen.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Color baseColor = Color.BLUE;
panelImage.setBackground(baseColor);
panelReference.setBackground(baseColor);
panelReference2.setBackground(baseColor);
baseType = BaseType.PURPLE;
}
});
You're stumbling in more ways that one.
In some sense, there is only one way to create a listener: there must be an object of a class that implements ActionListener, which means the class has the actionPerformed method.
There are three ways to do this:
You can modify a class you are already using for something else by marking it as implementing ActionListener and adding the actionPerformed method. This saves you creating a new class -- a savings of negligible value in most cases -- but mars otherwise perfectly good code. A few cases, when the existing
You can create a new named class. This is useful if you think the name is going to be meaningful to someone. If you are really using names like "MyListener", that's a clue that no, no-one cares about the name.
Finally, and usually, you can create an unnamed class. If all you want to do is add a fragment of code as a listener.
Whatever your choice, it's extremely unlikely to have any detectably effect on the time or memory performance of your finished system. The choice should be dictated by concerns about readability and maintainability.
In Swing I'm using ActionListener or any other Listener interface.
In general I can't create object of Interface.
If I use new operator with any constructor name a object is created.
I have a problem with my code below:
jbtOK : is some button object
ActionListener is an interface.
How can I use new ActionListener() in addActionListener method?
Since an object is created. but, I can't create a object from an interface.
Is it only possible in inner classes? i.e, in inner classes I can create objects of interface:
jbtOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
});
with the new keyword you create the object into the memory and as you create the object object of an interface it's need to be implement. lets compare with the explicit class
suppose you define the class which implement this ActionListener interface what you do?
class MyActionListener implements ActionListener{
// now here you need implement all of the method which defined into the ActionListener interface
}
now you can use this class to register listener for Action like this way
jbtOK.addActionListener(new MyActionListener());
this was the explicit implement and as you directly implement it's called Anonymous class as you defined here with ActionListener interface
If I understood your question, you cannot use the methods of an interface, because an interface has all its methods as abstract (empty, without implementation), then you have to implement all the methods requested by your interface.
For example, because you have to add an ActionListener to a button, then associate it to action called in actionPerformed method, you have to declare in the first lines of your code:
public class your_class implements ActionListener
Where the keyword implements is needed to indicate you are implementing the abstract methods of the ActionListener interface, or any other interface, to use these methods with your objects.
http://mindprod.com/jgloss/interface.html#INSTANTIATING:
You can’t instantiate an interface directly, but you can instantiate a class that implements an interface. References to an Object can by via the class name, via one of its superclass names, or one of its interface names.
Read also a few things about anonymous classes.
new class-name ( [ argument-list ] ) { class-body }
It is an anonymous class you are instantiating and passing to your addActionListener method. addActionListener takes an ActionListener as an argument, so since you provide an actionPerformed method it assumes that the anonymous class you pass to it is an ActionListener.
Try to change the name of this actionPerformed method. It will not work anymore since the anonymous class you are passing does not implement the ActionListener Interface. See the error message you get by the compiler.