在Java回调中使用接口的必要性是什么?

时间:2017-09-30 12:39:05

标签: java interface callback

这两个实现有什么区别?是否有必要使用界面?

第一个snipet使用接口,第二个不是

// interface implementation of callback
interface OnSearchListener {
    void onFound(String result);
}

class Main {

    public static void main(String[] args) {
        Search search = new Search();
        search.searchForSomething(new OnSearchListener() {
            @Override
            public void onFound(String result) {
                System.out.println(result);
            }
        });

    }
}

class Search {
    public void searchForSomething(OnSearchListener searchListener) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(200);
                System.out.println("searching....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        searchListener.onFound("found some result");

    }
}

****************

这是一个不使用接口的回调

class Search {
    public void searchForSomething() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(200);
                System.out.println("searching....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Main main = new Main();
        main.onFound("found some result");
    }
}

class Main {

    public void onFound(String result) {
        System.out.println(result);
    }

    public static void main(String[] args) {
        Search search = new Search();
        search.searchForSomething();

    }
}

在回调中使用界面的重要性是什么?什么是不使用它的利弊?

3 个答案:

答案 0 :(得分:0)

如果你有多个实现,接口总是很好用。如果你在场景中提到了不同版本的onFound怎么办?

答案 1 :(得分:0)

术语“回调”不适合第二种实现,因为这只是一种固定的方法调用。

“回调”意味着我向某个函数(OnSearchListener)提供代码(在您的情况下为onFound()的{​​{1}}方法),要求它在某些条件时调用我的代码满足。因此,在提供的代码中没有任何可变性,它不是回调。

当然,如果您完全控制双方(searchForSomething()Main),并且只想要一个被剪切的代码被调用,那么您不需要回调,这就是您的第二次实施。

但是如果你想要一个真正的回调,你需要一个定义方法签名的抽象,但不是要调用的实现,而且通常是Java中的接口,但是(坏样式!)也可能是抽象类甚至是普通的基类。

答案 2 :(得分:0)

您正在比较苹果和橘子。

  • 第一种情况是回调。
  • 第二种情况不是回调。

在第二种情况下,您用Main创建了一个Main main = new Main();的新实例,所以这不是回调。在回调中,您将回调Main的现有实例,以返回搜索结果。

您可以将Main设置为一个单例,这样就只会有Main的一个实例,但是类之间的通信方式超出了您的问题范围,并且有一些缺点,具体取决于您用例。