JavaRush /Java Blog /Random-JA /Javaの匿名クラス

Javaの匿名クラス

Random-JA グループに公開済み
こんにちは!今日のレッスンでは、引き続きネストされたクラスのトピックを見ていきます。次は最後のグループ、Java の匿名内部クラスの番です。図に戻りましょう。 匿名クラス - 2前回の講義で説明したローカル クラスと同様、匿名クラスは内部クラスのサブセットです。また、それらの間にはいくつかの類似点と相違点もあります。しかし、まず最初に、なぜ実際に「匿名」と呼ばれるのかを考えてみましょう。これを行うために、簡単な例を見てみましょう。常に実行されて何かを行っているメイン プログラムがあると想像してください。いくつかのモジュールで構成されるこのプログラムの監視システムを作成したいと考えています。1 つのモジュールは一般的なパフォーマンス指標を監視してログを保持し、2 つ目のモジュールはエラーを記録してエラー ログに記録し、3 つ目のモジュールは不審なアクティビティ (たとえば、不正アクセス試行やその他のセキュリティ関連のもの) を監視します。3 つのモジュールはすべて、基本的にプログラムの先頭で開始し、バックグラウンドで実行する必要があるため、それらに共通のインターフェイスを作成することをお勧めします。
public interface MonitoringSystem {

   public void startMonitoring();
}
これは 3 つの特定のクラスによって実装されます。
public class GeneralIndicatorsMonitoringModule implements MonitoringSystem {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Security monitoring started!");
   }
}
すべてが順調に進んでいるように見えます。私たちはいくつかのモジュールからなるかなり明確なシステムを持っています。それぞれに独自の動作があります。新しいモジュールが必要な場合は、実装が非常に簡単なインターフェイスを備えているため、モジュールを追加できます。しかし、監視システムがどのように機能するかを考えてみましょう。 基本的には、 、、 - の 3 つのオブジェクトを作成し、それぞれのオブジェクトに対してメソッドを呼び出す匿名クラス - 3だけです。つまり、3 つのオブジェクトを作成し、それらに対して 1 つのメソッドを呼び出すだけです。 GeneralIndicatorsMonitoringModuleErrorMonitoringModuleSecurityModulestartMonitoring()
public class Main {

   public static void main(String[] args) {

       GeneralIndicatorsMonitoringModule generalModule = new GeneralIndicatorsMonitoringModule();
       ErrorMonitoringModule errorModule = new ErrorMonitoringModule();
       SecurityModule securityModule = new SecurityModule();

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
コンソール出力:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
そして、このような小さなジョブのために、3 つのクラスと 1 つのインターフェイスからなるシステム全体を作成しました。これらすべては 6 行のコードのために行われます。一方、私たちの選択肢は何でしょうか?はい、このような「使い捨て」クラスを作成するのはあまりクールではありません。しかし、どうすればこれを修正できるでしょうか? ここで、匿名の内部クラスが役に立ちます。私たちの場合は次のようになります。
public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Monitoring of general indicators has started!");
           }
       };



           MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Security monitoring started!");
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
ここで何が起こっているのか見てみましょう! インターフェイス オブジェクトを作成しているようです。
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
};
しかし、インターフェイス オブジェクトを作成することが不可能であることは、長い間知られていました。そうです、それは不可能です。実際、私たちはそんなことはしません。私たちが次のように書いた瞬間:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Java マシン内では次のことが起こります。
  1. を実装する名前のない Java クラスが作成されますMonitoringSystem
  2. コンパイラは、そのようなクラスを認識すると、すべてのインターフェイス メソッドを実装することを要求しますMonitoringSystem(これを 3 回実行しました)。
  3. このクラスのオブジェクトが 1 つ作成されます。コードに注目してください。
MonitoringSystem generalModule = new MonitoringSystem() {

};
最後にセミコロンが付いています!彼女は理由があってそこに立っている。同時にクラスを宣言し (中括弧で)、そのオブジェクトを作成します。(); 3 つのオブジェクトはそれぞれ、startMonitoring()独自の方法でメソッドをオーバーライドしています。最後に、それぞれに対してこのメ​​ソッドを呼び出すだけです。
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
コンソール出力:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
それだけです!タスクは完了しました。3 つのオブジェクトを作成しMonitoringSystem、3 つの異なる方法で再定義し、3 回呼び出しました。3 つのモジュールはすべて正常に起動され、動作しています。同時に、プログラムの構造もはるかにシンプルになりました。GeneralIndicatorsMonitoringModule結局のところ、クラスをプログラムから完全に削除できるようになりましErrorMonitoringModuleた。SecurityModule私たちは単にそれらを必要としていません - それらなしでも問題なく対処できました。匿名モジュール クラスのそれぞれに異なる動作、つまり他のクラスにはない独自のメソッドが必要な場合は、それらを簡単に追加できます。
MonitoringSystem generalModule = new MonitoringSystem() {

   @Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }

   public void someSpecificMethod() {

       System.out.println("Specific method for first module only");
   }
};
Oracle のドキュメントには、「1 回限りの使用にローカル クラスが必要な場合は、匿名クラスを使用する」という優れた推奨事項があります。匿名クラスは完全な内部クラスです。したがって、静的変数やプライベート変数を含む外部クラス変数にアクセスできます。
public class Main {

   private static int currentErrorsCount = 23;

   public static void main(String[] args) {

       MonitoringSystem errorModule = new MonitoringSystem() {

           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }

           public int getCurrentErrorsCount() {

               return currentErrorsCount;
           }
       };
   }
}
これらはローカル クラスと共通点があります。つまり、それらが定義されているメソッド内でのみ表示されます。上の例では、メソッドのerrorModule外でオブジェクトにアクセスしようとするとmain()失敗します。そして、匿名クラスがその「祖先」である内部クラスから継承したもう 1 つの重要な制限:匿名クラスには静的変数と静的メソッドを含めることはできません。上記の例のメソッドを静的にしようとするとgetCurrentErrorsCount()、コンパイラはエラーをスローします。
//error! Inner classes cannot have static declarations
public static int getCurrentErrorsCount() {

   return currentErrorsCount;
}
静的変数を宣言しようとすると、同じ結果が得られます。
MonitoringSystem errorModule = new MonitoringSystem() {

   //error! Inner classes cannot have static declarations!
   static int staticInt = 10;

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }

};
最後に、匿名クラスのトピックに関する優れたビデオをお勧めします。このトピックはできるだけ簡単かつ明確に説明されています :)
そして今日のレッスンも終わりました!ネストされたクラスの最後のグループについて説明しましたが、このトピックはまだ終わっていません。次に入れ子になったクラスについて何を勉強するのでしょうか? 必ずすぐに分かりますよ!:)
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION