ホームページ  >  記事  >  Java  >  Javaコールバック関数についてもう一度話しましょう

Javaコールバック関数についてもう一度話しましょう

高洛峰
高洛峰オリジナル
2017-01-24 13:41:19968ブラウズ

またコールバック関数に出会ったので、今回はそれを書き留めて共有する予定です。

いわゆるコールバック関数、オブジェクト指向言語のコールバックメソッドとは、簡単に言うと、ある時点(イベントが発生する)に呼び出される関数のことです。

もっと詳しく言うと、関数 A がパラメータとして別の関数 B に渡され、ある時点で B によって呼び出されます。

ここで、ある関数が別の関数を呼び出すことができるのに、呼び出される別の関数にその関数をパラメータとして渡す必要があるのはなぜでしょうか? (java など) パラメータとしての関数はサポートされていません。

はい、確かに関数本体で別の関数を呼び出すことができます。関数に違いはないようですが、ここで問題があります。つまり、呼び出したい関数がハードコーディングされているということです。つまり、関数 B です。関数 A のみを呼び出すことができるので、別のシナリオで、A とは異なる関数 C があり、B の特定の時点で呼び出す必要がある場合はどうなるでしょうか。

コールバック関数について話を続けましょう。C/C++ では、関数ポインターをパラメーターとして使用して、コールバック関数を別の関数から呼び出すことができます。C# では、デリゲートを使用できます。イベント メソッドの場合は、そこでコールバック関数を呼び出すことができます。 Python と JavaScript では、これらの言語はすべてコールバック関数 (メソッド) を実装するのが非常に簡単ですが、最初に話が逸れてしまいました。 C#を勉強しましたが、将来はJavaを使わなくなる予定でしたが、現実はそれほど理想的ではなく、Androidを作りたいと思っています。そして今日、私はこのコールバック関数の問題に遭遇しました。これは私もこのブログで遭遇しましたが、Java を除いて、コールバックを簡単に実装できると個人的には思います。 Java の場合もそうだと思います。そうでなければ、私はこのブログを書いていないでしょう。

さて、Java でのコールバック メソッドの実装について話を続けましょう。このブログの焦点は Java です。 Java では、コールバック メソッドはインターフェイスを借用して実装されます。

「あるインターフェイスを実装したクラスが作成したオブジェクトの参照を、そのインターフェイスで宣言されたインターフェイス変数に代入し、そのインターフェイスの変数を代入する」という文を見つけました。実装されたインターフェイスのメソッドを呼び出すことができます。」
非常に紛らわしいので、簡単に説明します:
インターフェイスがあり、インターフェイス内にメソッドがあります (このメソッドはコールバックされるメソッドです):

interface CallBackInterface {
  void callBackMethod();
}

インターフェイス オブジェクトは使用できないことがわかっています内部のメソッドは何も実装されていないため、直接的に。したがって、このインターフェイスを実装するクラスを見つけてください。
それでは、このインターフェースを実装するクラスを追加します:

interface CallBackInterface {
  void callBackMethod();
}
 
class CallBackClass implements CallBackInterface{
 
  @Override
  public void callBackMethod() {
    System.out.println("hello");
  }
}

さて、最後のステップ: インターフェースを実装するクラスのオブジェクトを、宣言されたインターフェース変数に割り当てます (メソッドにそれを書き、その後、外部に書きました)クラスシェルを追加しました):

public class CallBackTest {
 
  interface CallBackInterface {
    void callBackMethod();
  }
 
  class CallBackClass implements CallBackInterface {
 
    @Override
    public void callBackMethod() {
      System.out.println("hello");
    }
  }
 
  public void showCallBack() {
    CallBackInterface itfs = new CallBackClass();
    itfs.callBackMethod();
  }
}

これで、呼び出して試すことができます:

public class Test {
  public static void main(String[] args) {
    new CallBackTest().showCallBack();
  }
}

事故がなければ、hello が正常に出力されます。とにかく、それはここにあります。

例を読んだ後、では、具体的には、特定のメソッドで呼び出す必要があるメソッドがあります (このメソッドはコールバック メソッドです)。呼び出したいメソッドを直接呼び出さないことが最善です。この問題は呼び出し側のメソッドに直接記述されており、Java ではメソッドをパラメータとして渡すことができないため、このコールバック メソッドをインターフェイスに配置する必要があります (なぜクラスではないのでしょうか? 抽象クラスではなく、インターフェイスでしょうか?自分でそこに行って、抽象クラスとインターフェイスの類似点と相違点を見つけて、この問題を自分で解決できます)。インターフェイスがある場合は、そのインターフェイスをクラスによって実装する必要があります。インターフェイスのオブジェクトに実装クラスのオブジェクトが割り当てられている限り、このインターフェイスのオブジェクトはそのメソッドを呼び出すことができます。これを理解するために、ここで使用されるポリモーフィズムの知識は、インターフェイスのオブジェクトがサブクラスによって正常に割り当てられ、サブクラスのオーバーライドされたメソッドを呼び出すことができるということです (クラスにも同様の概念があります)。

もう 1 つ、CallbackInterface インターフェイスを実装するクラスは、次のように new の後に配置できます (つまり、代入):

public class CallBackTest {
  interface CallBackInterface {
    void callBackMethod();
  }
 
  class CallBackClass implements CallBackInterface {
 
    @Override
    public void callBackMethod() {
      System.out.println("hello");
    }
  }
 
  class Controller {
    private CallBackInterface cbitf;
    // 这个boolean只是为了模拟有事件,没啥实用价值
    public boolean somethingHappend;
    // 这里确实可以直接把CallBackClass做参数,而且省掉接口的定义
    // 但是这样做的话,就像是回调函数直接写在了调用函数里一样
    // 不明白的话就好好理解下"约定"和"调用者不管回调函数是怎么实现的"吧
    public Controller(CallBackInterface itfs) {
      somethingHappend = true;
      this.cbitf = itfs;
    }
 
    public void doSomething() {
      if(somethingHappend) {
        cbitf.callBackMethod();
      }
    }
  }
 
  public void showCallBack() {
    CallBackClass cbc = new CallBackClass();
    Controller ctrlr = new Controller(cbc);
    ctrlr.doSomething();
    // 其实上面也可以这样写在一行里
    // new Controller(new CallBackClass()).doSomething();
  }
}

最後にもう 1 つ、実際、この種のアプリケーションは次のようになります。 Androidで使われている よく遭遇するのですが、私はAndroidを勉強していた時に遭遇しました。

上記はコールバック関数の個人的な理解と使用法です。皆さんに気に入っていただければ幸いです。

Java コールバック関数に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。