How can you instantiate an Interface? - java

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.

Related

Intitialising an object of an interface as an argument of a method?

As I am aware, you cannot make objects of interfaces, instead objects of classes that implement an interface, however, whilst looking at a tutorial on event handlers I found the following:
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
tf.setText("Welcome to Javatpoint.");
}
});
First of all, I didn't know you could construct an object within the arguments of a method. Second, I know that ActionListener is an interface, so what exactly is the new ActionListener doing here? After reading around I get the vague idea that this is actually making a new class that implements Action Listener, but what is this class called? Can I make other objects of this class? And finally, how exactly is the above code any different from the following:
//where MyActionListener is a class that implements ActionListener
MyActionListener objectOfActionListener = new MyActionListener();
b.addActionListener(objectOfActionListener);
//and the method for actionPerformed is in the MyActionListener class
This is an anonymous class that implements the ActionListener interface.
You could of course create an explicit class of your own and instantiate it, but unless you need to reuse the same logic in more than one place, there's no big benefit in it.

Anonymous classes and interfaces

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.

When to use inner classes over decoupled design?

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.

Must implement the inherited abstract method

My class implements ActionListener. I have implemented the following nested classes below:
JMenuItem mntmNew = new JMenuItem("New...");
mntmNew.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
doNew(e); //calls to outer class for cleaner code
}
});
mnFile.add(mntmNew);
JMenuItem mntmLoad = new JMenuItem("Load...");
mntmLoad.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
doLoad(e); //calls to outer class for cleaner code
}
});
mnFile.add(mntmLoad);
//etc. for the rest of the menu system
However, Eclipse is still telling me that my class must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent e). Can you not implement override methods in a nested class in this way?
Your question:
Can you not implement override methods in a nested class in this way?
The answer is no. Eclipse (actually Java) is complaining that while you're declaring your class as implementing ActionListener you're not giving your class the necessary actionPerformed(...) method in the class's own scope -- and this last part is very important. The class that implements the interface must implement all the interface's required methods in its own scope and not in nested classes. Note that this doesn't prevent you from nesting classes that also implement ActionListener or other interfaces, but regardless, the rule remains that a non-abstract class that implements an interface must override all of the interface's methods.
But since you're not using objects of your class as an ActionListener, the simple solution is to not declare your class as implementing the ActionListener interface. Problem solved. And actually you're far better off not having your GUI class implement your listener interfaces since combining them in one class is asking a class to do too much. In technical terms, it unnecessarily reduces a class's cohesion and risks increasing it's coupling reducing its readability and maintainability.

Can Java interfaces have constructors?

ActionListener is a interface but why can i create instance object?
JButton button = new JButton("Button1");
ActionListener me = new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(null,ae.getActionCommand());
}
};
button.addActionListener(me);
Or what else? I am not sure. Please help me.
What you're seeing here is called an anonymous class: me will be assigned an instance of an anonymous (un-named) class that implements the ActionListener interface.
Unlike say C#, Java's interfaces cannot prescribe a constructor.
What you are doing in your code is creating an anonymous class that extends java.lang.Object (which does have a default constructor) and implementing the interface.
What you have instantiated is an Anonymous Inner Class. In short, it's an in-line way to both define a class that has no name and instantiate an instance of that class in one statement. You'll only ever be able to refer to anonymous inner classes by the super class they implement or extend. In the case of this question, the super class is the ActionListener interface.
When you compile your code, there will be an extra .class file that exists with a name like this: OuterClass$1.class. That is the class file that represents the anonymous inner class you've defined.
If you want to learn more, check out this section in the JLS http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5
Because you're implementing the interface with your anonymous class
ActionListener itself is an interface, indeed.
However, the construct in your code is an anonymous inner class, meaning that your interface was implemented by that inner class.
Actually, what you are creating is an anonymous subclass of Object.class that implements the interface. So you are "inheriting" the Constructor from Object, not from the interface.
You are not creating an instance of ActionListener. You are creating an anonymous class which implements ActionListener and you are providing that implementation.
ActionListener is in fact an interface which can not be instantiated.
However, by defining public void actionPerformed() locally you are allowing the interface to act like a class.
This is legal:
ActionListener me = new ActionListener(){
public void actionPerformed(...){...};
};
This is not:
ActionListener me = new ActionListener();
1. You can't have constructor in Interface in java.
2. What you saw here is an Anonymous Class, which is declared and initialized simultaneously, and it must extend or implement a class or interface respectively.

Categories

Resources