22

リスナーとアダプターを区別しようとしています。

それらはほとんど同じですが、リスナーではインターフェイスのすべてのメソッドを実装する必要がありますが、アダプターでは必要なメソッドのみを実装するオプションがあり、コードがよりクリーンで読みやすくなりますか?

また、アダプターは 1 つの実装のみでインスタンス化を有効にし、リスナーをインスタンス化できないとも言われましたが、これは完全には理解できません。

誰かがどちらを使用するのが良いか、一方を使用するとできること、もう一方を使用するとできないことを説明できますか?

4

5 に答える 5

32

WindowListenerはすべてのメソッドinterfaceを強制しますが、 WindowAdapterは実装であり、処理する必要があるメソッドのみが必要です。overrideWindowListeneroverride

WindowListenerはインスタンス化できないことを意味するインターフェイスでありWindowListener、は演算子をWindowAdapter使用してインスタンス化できる具象クラスです。new

を使用するWindowAdapterと、クラスが必要なメソッドのみをオーバーライドするため、コードがよりクリーンになります。例えば:

ウィンドウリスナー

public class CloseListener implements WindowListener {
    // im not interest  on this event, but still need to override it
    @Override
    public void windowOpened(WindowEvent e) {

    }
    // im not interest  on this event, but still need to override it    
    @Override
    public void windowClosing(WindowEvent e) {

    }

    @Override
    public void windowClosed(WindowEvent e) {
        System.exit(0);

    }
    // im not interest  on this event, but still need to override it    
    @Override
    public void windowIconified(WindowEvent e) {

    }
    // im not interest  on this event, but still need to override it
    @Override
    public void windowDeiconified(WindowEvent e) {

    }

}

WindowAdapter

アダプターを使用すると、コードがよりクリーンになります。

// at JFrame class
addWindowListener(new CloseListener());

// reusable Close Listener
public class CloseListener extends WindowAdapter {
    @Override
    public void windowClosed(WindowEvent e) {
        System.exit(0);
    }
}

または

addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosed(WindowEvent e) {
         System.exit(0);
     }
});

したがって、 を使用することをお勧めしますWindowAdapterが、従う必要はありません。WindowAdapterただし、リスナー オブジェクトを作成するための便宜上、同じような API が 2 つ存在します。

編集:

WindowListenerisであるためinterface、JFrame サブクラスで実装できます。

public class MainWindow extends JFrame implements WindowListener {
    // this is ok
}
public class MainWindow extends JFrame, WindowAdapter {
    // this is not allow
}

しかし、あなたはそれを行うことはできませんWindowAdapter

于 2012-05-06T11:20:32.247 に答える
8

どちらでもすべてを行うことができますが、インターフェイスから始めると、コードにはボイラープレートがたくさん含まれます。使ってみて気づいたことがあると思います。インスタンス化などに関するそのステートメントは、非常に複雑な言い方であり、用語の混乱がたくさんあります。あなたは書ける

c.addWindowListener(new WindowListener() {
  @Override public void windowActivated(WindowEvent arg0) { }
  @Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
  @Override public void windowClosing(WindowEvent arg0) { }
  @Override public void windowDeactivated(WindowEvent arg0) { }
  @Override public void windowDeiconified(WindowEvent arg0) { }
  @Override public void windowIconified(WindowEvent arg0) { }
  @Override public void windowOpened(WindowEvent arg0) { }
});

またはあなたが書くことができます

c.addWindowListener(new WindowAdapter() {
  @Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
});

どちらの場合も、インスタンス化していないか、WindowListenerまたは/extendWindowAdapterを実装する匿名クラスを作成しています。ただし、インターフェイスを直接実装すると、すべてのメソッドを実装する必要がありますが、アダプター クラスを拡張すると、必要なものだけをオーバーライドできます。そのクラスには、このケースで記述しなければならなかったまさにこれらの空の実装が既に含まれています。WindowListenerWindowAdapterListener

于 2012-05-06T11:21:37.833 に答える
0

リスナーは、ほとんどのインターフェイス メソッドを利用する場合に使用されます。いくつかのメソッドのみを使用する必要がある場合は、アダプタの方が優れているため、残りのメソッドをオーバーライドする必要はありません。

于 2012-05-06T15:20:05.913 に答える
0

他の回答では扱われていない別の側面があります: API の進化です。アダプター クラス (インターフェイスの空の実装または既定の実装) を提供すると、インターフェイスに新しいメソッドを導入する際の負担が軽減されます。API がインターフェイスのみを提供する場合、クライアントはそれらを実装することを余儀なくされ、新しいメソッドがインターフェイスに追加されると、すべての実装クラスが壊れます。ただし、デフォルトの実装が提供されている場合、クライアントは代わりにそれらを拡張する機会があり、便利であるだけでなく、新しい API バージョンへのアップグレードに役立ちます。Java 8 の default/empty 実装のデフォルト メソッドはあまり重要ではなくなりましたが、古いバージョンでは便利かもしれません。

于 2016-12-19T09:52:18.257 に答える
0

MouseAdapter、KeyAdapter、WindowAdapter などのいくつかのアダプタ クラスを拡張できるため、実際には必要のないメソッドを記述する必要がありません。

インターフェースの問題は、必要のないメソッドをすべて書き出さなければならないことです。必要なメソッドをオーバーライドする方法として、Adapter クラスをさらにサブクラス化できます。

http://www.cafeaulait.org/course/week7/19.html

于 2012-05-06T11:38:41.260 に答える