Difference between callback and interface - java

What is the difference between these two piece of code
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
is that inner interface of View class, if so we know that interface can not be instantiated
And here
soInterface.getAnswers().enqueue(new Callback<SOAnswersResponse>() {
#Override
public void onResponse(Call<SOAnswersResponse> call, retrofit2.Response<SOAnswersResponse> response) {
}
#Override
public void onFailure(Call<SOAnswersResponse> call, Throwable t) {
}
});
its callback that it required in the enqueue method, what this syntax define, is it interface "CallBack<>" defined some where and we are calling it here as inline interface, but again interface can not be instantiated like callback syntax says "new CallBack(){}"

What is the difference between these two piece of code
Both are 2 different interface
View.OnClickListener - this interface helps you to listen to the View click action
Callback<SOAnswersResponse> - Try to get the response from the server

Both of them are interfaces:
CallBack is represents that the response(Callback) of Retrofit and when it is present you go into the onResponse or it failed to comeback (in the 10s time frame), be read(wrong parsing), or other reasons then onFailure will be executed.
While onClickListener will be listening to button click.
you can implement an interface of onClick listener in the Activity or Fragment and use button.setOnClickListener(this) same for Retrofit.

Both classes in this case are interfaces with a callback. The anonymous class implements View.OnClickListener which has a callback on onClick. Same goes for the anonymous class implementing Callback<SOAnswersResponse>(). This time it has a typed parameter and two callbacks for onResponse and onFailure.
The statement that interfaces can not be instantiated is true, but you can create an anonymous class of it. See Can we create an instance of an interface in Java?

Both View.OnClickListener and Callback are interfaces.
OnClickListener is nested inside View class. Retrofit Callback is not nested.
This is the Callback interface doc: https://square.github.io/retrofit/2.x/retrofit/retrofit2/Callback.html
interface can not be instantiated
We instantiate an anonymous class here. i.e. We implement the interface as an anonymous class and instantiate that anonymous class on the fly.
From the Java doc:
They [Anonymous class] 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.

You're correct, it is not possible to instantiate an interface. An interface is the definition of a set of methods that must be implemented by a concrete class.
What your code is using, in both cases, is an anonymous inner class. The Java syntax allows you to specify that you would like a new instance of 'something' that implements the specified interface but you don't want to write all the code to do that. Your code only provides the implementations of the abstract methods defined by that interface.
If you look at the class files for your application you will see something like MyClass$1.class, which is a class file generated synthetically by the compiler. The compiler creates a class called MyClass$1 that implements the interface you've specified with the methods you've defined. The compiler will then make your code look something like this before compiling it:
btn.setOnClickListener(new MyClass$1());
The same applies to the second example but with a different interface, etc.

Related

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.

Why do we use an interface for callbacks rather than just passing a reference to the activity

I am not very familiar with interfaces so i am wondering, what is the difference between passing a reference of an activity to an asynctask, then calling a method of that activity in onPostExecute. what is the difference between these those examples, why should interface be used instead
Interface example
public interface OnTaskCompleted{
void onTaskCompleted();
}
Activity:
public YourActivity extends Activity implements OnTaskCompleted{
}
AsyncTask:
public YourTask extends AsyncTask<Object,Object,Object>{
private OnTaskCompleted listener;
public YourTask(OnTaskCompleted listener){
this.listener=listener;
}
protected void onPostExecute(Object o){
listener.onTaskCompleted();
}
}
activity example
Activity:
public YourActivity extends acitivty {
public myCallbackMethod(){
//do something
}
}
AsyncTask
public YourTask extends AsyncTask<Object,Object,Object>{
private YourActivity act;
public YourTask(YourActivity act){
this.act=act;
}
protected void onPostExecute(Object o){
act.myCallbackMethod();
}
}
This is primarily a matter of taste and design style. The interface provides the advantage that you are not required to send an Activity to the AsyncTask. Instead you can choose to create a separate class which implements the interface.
I just want to make above answer be clearer so:
The differences is not showing here clearly. but in general and in the world of OOP, you can find a lot of examples that make you use this fundamental principal of design pattern program to interface. here is a quick example that make you use this pattern:
consider you have an object A as a base class and you pass it to your other class B to call method f of class A, so in this scenario you must declare A in the header of a function of B. So obviously B only accepts A and its children. now consider you want a class called C to have a function f and you want to call that function from B. obviously it is not a good idea to extend C from A because they do not have any Is-A relationship so what should you do? again declaring another function in B to accept a reference from C. it is not a good idea because after a while you may need other object called D to call its f method. so to prevent those situation you declare an interface and make every class to implement that, in this scenario all you have to declare in object B is a method that accept that interface as a reference. every object that is implements that interface can pass to your B class.
now consider you want to create a library and you need to call a method from your user object. for example calling a method that the requested image has been downloaded successfully. if you accept the reference of activity user must just use your code in the activity and can not use it from services. so you must provide different functions that accept services, activity, fragment and so on. instead of that you just say I accept only this interface, every one wants to use implement that.

Instantiating Java object with a passed in method

It's been a few years since I've been heavily into Java. Coming back to it I'm seeing this pattern all over the place:
ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
// do work
}
});
This looks more like Functional programming to me. It's a nice pattern but how is it possible to pass a method like this? In the old days a class was a class, and once compiled there was little you could do to it.
My questions are:
Can anyone let me know what this pattern is called?
How can I write a class that can be instantiated in this way.
Are there any other useful examples of functional patterns that have made their way into Java?
What do I need to Google to read more about this?
Thanks.
This passes an anonymous class, not a method.
This is a typical pattern, not just in Swing programming, but anywhere you need (hopefully) short, "throw-away" implementations of an interface or class that doesn't need to be re-used, instead of creating a full-blown implementation.
Any class/interface can be instantiated like this, there's nothing special about it:
public interface Foo {
String foo();
}
...
public class Main {
public static void main(String[] args) {
System.out.println(new Foo() {
public String foo() {
return "plugh";
}
});
}
}
Anonymous inner classes get their own class files, too, even though their source is embedded.
In this example, a Main$1.class file will be generated for the anonymous inner class, in addition to the expected Main.class file.
The statement: new OnRatingBarChangeListener() creates a new instance of a class. The following part inside the curly braces is the definition of the class.
In this case that class in an anonymous class that implements the named interface.
Anonymous classes are classes, that are declared without a name, and thus, can not be used like regular named classes.
This pattern is very common when using listeners, that often contain only a single to a few methods that do an almost trivial task.
This is the Listener pattern. Rating bar takes an implementation of OnRatingBarChangeListener and calls its onRatingChanged method on the appropriate event.
You can use instance of any class which implements OnRatingBarChangeListener. So you can use either a named class of your own or you can pass it an anonymous class like in the example. The anonymous class in the example is effectively a unnamed class which extends Object and implements OnRatingBarChangeListener. Since the class isn't named it cannot be referenced and so the instance passed is the only instance existing.
This is called "Observer pattern". A good example for this is adding action listeners for java button or other component. For example,
myButton.addActionListener(
new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Work here
}
});
In here "myButton" is the subject and ActionListener is the observer.

Polymorphic function calls in Java?

Is it possible to polymorphically pass a function to an object array in Java?
I'm trying to create an event-based system, and interfaces simply isn't as versatile as I would like it to be.
As a result, I would like to be able to pass any function to the event manager, and have it execute the function on next iteration.
I would like to be able to pass any function to the event manager
Wouldn't we all. Unfortunately, Java doesn't have first-class functions or even function pointers. So we're stuck with interfaces and anonymous classes, until Java 8 at least.
Why not have your event manager execute Runnables, and wrap your method call with one? (This is the approach Swing took.)
public class Foo {
public void doSomething(){
System.out.println("Hello");
}
}
EventQueue.doLater(new Runnable(){
public void run(){
new Foo().doSomething();
}
}
I'm not sure why Interfaces aren't versatile enough for you - you can do anything you like with interfaces, certainly as much as you could do with passing pure functions.
Typically you would just define a single event handler interface:
public interface EventHandler {
public ReturnType handle(ParamType param);
}
Then you could implement that interface with any number of different handler classes. The handler objects can even contain their own state if that is useful.
Anything you define that implements the interface can then be used polymorphically, e.g. stored in an array so that they can be called in response to a specific event..
Java doesn't support first-class functions.
But you can do almost that by using anonymous classes or using EventHandler class.
This is from Java Docs.
The simplest use of EventHandler is to install a listener that calls a method on the target object with no arguments. In the following example we create an ActionListener that invokes the toFront method on an instance of javax.swing.JFrame.
myButton.addActionListener(
(ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));
When myButton is pressed, the statement frame.toFront() will be executed. One could get the same effect, with some additional compile-time type safety, by defining a new implementation of the ActionListener interface and adding an instance of it to the button:
//Equivalent code using an inner class instead of EventHandler.
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.toFront();
}
});

Anonymous Inner Class request for clarification

While learning TTS on Android, I came across the following code snippet:
speakBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}});
I am really new to Java, so my level of confidence in identifying the various constructs isn't that great. I think that I see above is an Anonymous Inner Class but the 'new OnClickListener()' is confusing to me. So please confirm and/or correct any of the following understanding:
The inner class is defined right
after new OnClickListener().
OnClickListener is a super class
from which the inner class is
derived.
The (anonymous) inner class has only
one member function: OnClick().
What is #Override inside the
definition of the inner class? If
this is an annotation, then I am
confused as this answer states
that anonymous inner classes cannot
be annotated.
Lastly, is there a way to write the above snippet in a way that is easier to decipher for a n00b like me?
Yes; it's defined between the braces.
Yes, except that it's an interface, not a class.
Yes.
You cannot add class-level annotations.
#Override is a method-level annotation, which works fine.
Well, basically this snippet of code creates a class which name is mangled by the compiler for your convinience so that you need'nt care about naming it yourself. That class will implement the interface OnClickListener, and contain implementation for the method onClick(View), as the interface requires.
As such, your snippet could be writter some way like this:
class OnClickListenerThingy01 implements OnClickListener { // name is invented from the top of my head and corresponds actual name manging in no way
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
speakBtn.setOnClickListener(new OnClickListenerThingy01());
The #Override annotation is not placed on the class itself - which has no declaration in your code the annotation could be added, being compiler-generated - but on the method.
The #Override annotation is used to mark overrides (how surprising) and method implementations. Its main use is to generate a compiler error if the signature of the overridden method changes, but you fail to update the overriding declaration accordingly, so that you won't get really surprised when you overrides fail to work, because, say, what was overridden was renamed.
In case on an interface implementation, if you forget to implement an interface fully, the compiler will generate an error anyways, so #Override may seem a bit redundant, but it is not. In fact, it is a rather nice thing to have so that unneccessary methods (when for example, a method declaration is removed from an interface) won't stay in your code.
Although it must be noted that an IDE like Eclipse will most probably make these concerns void, as the provided refactoring tools are more than enough to avoid such situtation. Anyways, #Override is quite nice to have on you methods when it may be used.
Here's a way to rewrite your snippet that makes it much clearer "to a noob" :)
class MyOuterClass {
private class MyOnClickListener implements OnClickListener {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
// later (inside some method)...
speakBtn.setOnClickListener(new MyOnClickListener());
}
The inner class is defined right after new OnClickListener().
Think of the code there as describing an unnamed subclass of OnClickListener(). The class definition is within the brackets, just as you thought.
OnClickListener is a super class from which the inner class is derived.
Yes
The (anonymous) inner class has only one member function: OnClick().
It does, but that does not have to be the case. It could have more member functions.
What is #Override inside the definition of the inner class? If this is an annotation, then I am confused as this answer states that anonymous inner classes cannot be annotated.
#Override is used for compile-time error-checking on methods. You can use method-level annotations on an anonymous inner class.
OnClickListener is a super class from
which the inner class is derived
Not really : OnClickListener is not a class.
This syntaxis is used to create an instance of a new (anonymous) class which implements the interface OnClickListener. So you have only one method to implement : onClick().

Categories

Resources