简体   繁体   中英

Calling interface method of class

I was reading how volley callbacks are implemented here

and how we use it in our code is like this

JsonObjectRequest jsonrequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
       @Override
       public void onResponse(JSONObject jsonObject) {}

so how does Response class able to access its interface methods like this? new Response.Listener is not should be like this?

new Response().Listener();

accessing with object of response class?

where does this syntax came from, whats the logic?

new Response.Listener();

You're not instantiating Response, you're instantiating Listener (anonymously), which is an inner class(interface) of Response.

this

new Response().Listener();

is an instance method call, like new Integer(42).equals(42) or new Thread(..).start()

this

new Response.Listener()

is an anonymous inner class instantiation, like new View.OnClickListener(){..} , same as a static field/method access: Boolean.TRUE, Integer.compare(1,2) (you can see Response as a path to access the Listener class - if it makes it easier for you)

I will start from your last question:

where does this syntax came from, whats the logic? new Response.Listener();

this syntax means, there is a class Response that has an interface or class Listener defined in it (nested), in your case it's an interface , if you had a chance to look at source code of Response you may see something like this:

public class Response{
    :
    :
    :

    public interface Listener {
        :
        :
        public void onResponse(JSONObject jsonObject);
    }//Listener interface
}//Response class

is not should be like this? new Response().Listener();

No, your suggested code means, create a new instance from Response then call a method called Listener() from that object (Response)

while this new Response.Listener means create new instance of Listener which is defined inside Response

Bonus : now as Listener is an interface, you can't create instance of it. so what should be done is:

1- Create new class that implements Listener and overrides onResponse() and pass it as param to JsonObjectRequest(...)

ex,

public class MyListern implements Response.Listener{
    @Override
    public void onResponse(JSONObject jsonObject) {
        //put your implementation here ...
    } 
}//Response class

MyListern mMyListern = new MyListern();
JsonObjectRequest jsonrequest = new JsonObjectRequest(Request.Method.GET, url, null, mMyListern);

OR

2- create an anonymous inner class , and pass it as a param to JsonObjectRequest(...) (it's the way you posted in the question)

--EDIT: extra Bonus :) mMyListern is instance of the class MyListern, that implements Listener which is defined in Response so it's not Response class, it's MyListener.

you can think of Response.Listener as a path, if you say

c:\\users\\john\\Desktop

this is a path points to Desktop, that exists inside john , and john exists in users , so Desktop is NOT users

It is just a nested class(1). For instance:

public class A {
  ...
  public static class B { ... }
}

Class A is just like a package for class B, so to create a new instance you need to write

new A.B();

But actually that code is instantiating an anonymous class that extends the inner class:

B myB = new A.B() {
  //methods overriden here
};

(1) B can also be an interface. In that case you cannot instantiate it so the only option is creating an anonymous class. I've not read the current implementation of that Response class, so I don't know if Listener is a class or an interface

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM