【问题标题】:Calling interface method of class调用类的接口方法
【发布时间】:2018-01-15 15:29:09
【问题描述】:

我正在阅读如何实现 volley 回调 here

我们如何在代码中使用它是这样的

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

那么 Response 类是如何像这样访问它的接口方法的呢?新的Response.Listener不应该是这样的吗?

new Response().Listener();

使用响应类的对象访问?

这个语法是从哪里来的,逻辑是什么?

new Response.Listener();

【问题讨论】:

    标签: java android oop interface


    【解决方案1】:

    您不是在实例化 Response,而是在(匿名)实例化 Listener,它是 Response 的内部类(接口)。

    这个

    new Response().Listener();
    

    是实例方法调用,如new Integer(42).equals(42) or new Thread(..).start()

    这个

    new Response.Listener()
    

    是一个匿名内部类实例化,如new View.OnClickListener(){..},与静态字段/方法访问相同:Boolean.TRUE, Integer.compare(1,2)(您可以将 Response 视为访问 Listener 类的路径 - 如果它让您更容易)

    【讨论】:

    • 监听器是不能实例化的接口
    • @blackHawk 匿名
    • 所以我发布的代码是匿名访问内部类或访问匿名内部类的方法?
    • @blackHawk 您无法访问匿名内部类,这就是它们是匿名的原因。 Response.Listener 是访问内部类的方法。 new Response.Listener(){...} 是内部类的匿名实现
    • 谢谢 :) 你能在这里看到我的另一个问题吗stackoverflow.com/questions/45555970/recyclerview-and-gridview/…
    【解决方案2】:

    它只是一个嵌套类(1)。例如:

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

    A类就像B类的一个包,所以要创建一个新的实例你需要写

    new A.B();
    

    但实际上该代码正在实例化一个扩展内部类的匿名类:

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

    (1) B 也可以是接口。在这种情况下,您无法实例化它,因此唯一的选择是创建一个匿名类。我没有读过那个 Response 类的当前实现,所以我不知道 Listener 是一个类还是一个接口

    【讨论】:

    【解决方案3】:

    我从你最后一个问题开始:

    这个语法是从哪里来的,逻辑是什么?新的 Response.Listener();

    这种语法意味着,有一个类 Response 有一个接口或类 Listener 在其中定义(嵌套),在你的情况下它是一个 interface ,如果你有机会查看Response 的源代码,您可能会看到如下内容:

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

    是不是应该是这样的?新的 Response().Listener();

    不,您建议的代码意味着,从 Response 创建一个新实例,然后从该对象调用一个名为 Listener() 的方法(响应)

    而这个new Response.Listener 意味着创建Listener 的新实例,它在Response 中定义

    奖励:现在Listener是一个接口,你不能创建它的实例。 所以应该做的是:

    1- 创建implements Listener 并覆盖onResponse() 的新类并将其作为参数传递给JsonObjectRequest(...)

    例如,

    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);
    

    2- 创建一个匿名内部类,并将其作为参数传递给JsonObjectRequest(...)(这是您在问题中发布的方式)

    --编辑:额外奖励 :) mMyListern 是 MyListern 类的实例,它实现了在 Response 中定义的 Listener,所以它不是 Response 类,它是 MyListener。

    你可以把Response.Listener看作一条路径,如果你说的话

    c:\users\john\Desktop

    这是指向桌面的路径,存在于john 中,而john 存在于users 中,因此桌面 不是用户

    【讨论】:

    • 谢谢,是的,匿名,我不明白这个:MyListern mMyListern = new MyListern(); JsonObjectRequest jsonrequest = new JsonObjectRequest(Request.Method.GET, url, null, mMyListern);是响应类吗?
    • @blackHawk ,不,是MyListener 检查我的更新答案
    • @blackHawk 你可以把 Response.Listener 看作一个路径,如果你说c:\users\john\Desktop 这是一个指向桌面的路径,它存在于 john 内部,而 john 存在于用户中,所以桌面不是用户
    • 谢谢,你能看看我的另一个问题吗;)stackoverflow.com/questions/45555970/recyclerview-and-gridview/…
    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 2020-02-20
    • 2017-07-07
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    相关资源
    最近更新 更多