JavaRush /Blog Java /Random-MS /Kelas tanpa nama di Jawa

Kelas tanpa nama di Jawa

Diterbitkan dalam kumpulan
hello! Dalam pelajaran hari ini kita akan terus melihat topik kelas bersarang. Tiba giliran kumpulan terakhir - kelas dalaman tanpa nama di Jawa. Mari kembali ke rajah kami: Kelas tanpa nama - 2Seperti kelas tempatan yang kita bincangkan dalam kuliah lepas, kelas tanpa nama ialah subset kelas dalaman. Mereka juga mempunyai beberapa persamaan dan perbezaan antara mereka. Tetapi pertama-tama, mari kita fikirkan: mengapa mereka sebenarnya dipanggil "tanpa nama"? Untuk melakukan ini, mari kita lihat contoh mudah. Bayangkan kita mempunyai program utama yang sentiasa berjalan dan melakukan sesuatu. Kami ingin mewujudkan sistem pemantauan untuk program ini yang terdiri daripada beberapa modul. Satu modul akan memantau penunjuk prestasi umum dan menyimpan log, yang kedua akan merekod dan log ralat dalam log ralat, yang ketiga akan memantau aktiviti yang mencurigakan: contohnya, percubaan akses tanpa kebenaran dan perkara lain yang berkaitan dengan keselamatan. Memandangkan ketiga-tiga modul pada asasnya hanya perlu bermula pada permulaan program dan dijalankan di latar belakang, adalah idea yang baik untuk mencipta antara muka biasa untuk mereka:
public interface MonitoringSystem {

   public void startMonitoring();
}
Ia akan dilaksanakan oleh 3 kelas tertentu:
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!");
   }
}
Nampaknya semuanya teratur. Kami mempunyai sistem beberapa modul yang agak jelas. Setiap daripada mereka mempunyai perangai sendiri. Jika kita memerlukan modul baru, kita boleh menambahnya, kerana kita mempunyai antara muka yang agak mudah untuk dilaksanakan. Tetapi mari kita fikirkan bagaimana sistem pemantauan kita akan berfungsi. Kelas tanpa nama - 3Pada asasnya, kita hanya perlu mencipta 3 objek - GeneralIndicatorsMonitoringModule, ErrorMonitoringModule, SecurityModule- dan memanggil kaedah startMonitoring()pada setiap satu daripadanya. Iaitu, semua yang anda perlu lakukan ialah mencipta 3 objek dan memanggil 1 kaedah padanya.
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();
   }
}
Output konsol:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Dan untuk kerja kecil itu, kami menulis keseluruhan sistem: 3 kelas dan satu antara muka! Dan semua ini demi 6 baris kod. Sebaliknya, apakah pilihan kita? Ya, tidaklah hebat kami menulis kelas "pakai buang" sedemikian. Tetapi bagaimana kita boleh membetulkannya? Di sinilah kelas dalaman tanpa nama datang membantu kami ! Inilah rupa mereka dalam kes kami:
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();
   }
}
Mari kita fikirkan apa yang berlaku di sini! Nampaknya kami sedang mencipta objek antara muka:
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
};
Tetapi kami telah lama mengetahui bahawa mustahil untuk mencipta objek antara muka! Betul, mustahil. Sebenarnya, kami tidak berbuat demikian. Saat kita menulis:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Di dalam mesin Java perkara berikut berlaku:
  1. Kelas Java yang tidak dinamakan dicipta yang melaksanakan MonitoringSystem.
  2. Pengkompil, melihat kelas sedemikian, memerlukan anda untuk melaksanakan semua kaedah antara muka MonitoringSystem(kami melakukan ini 3 kali).
  3. Satu objek kelas ini dicipta. Beri perhatian kepada kod:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Terdapat koma bertitik di hujungnya! Dia berdiri di sana atas alasan. Kami secara serentak mengisytiharkan kelas (melalui pendakap kerinting) dan mencipta objeknya menggunakan (); Setiap daripada tiga objek kami telah mengatasi kaedah startMonitoring()dengan cara tersendiri. Pada akhirnya kami hanya memanggil kaedah ini pada setiap daripada mereka:
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Output konsol:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Itu sahaja! Kami telah menyelesaikan tugas kami: kami telah mencipta tiga objek MonitoringSystem, mentakrifkannya semula dalam tiga cara berbeza dan memanggilnya tiga kali. Ketiga-tiga modul berjaya dilancarkan dan berfungsi. Pada masa yang sama, struktur program kami menjadi lebih mudah! GeneralIndicatorsMonitoringModuleLagipun , kelas ErrorMonitoringModulekini boleh SecurityModuledialih keluar daripada program sama sekali! Kami tidak memerlukannya - kami berjaya dengan baik tanpa mereka. Jika setiap kelas modul tanpa nama kami memerlukan beberapa tingkah laku yang berbeza, kaedah khusus tersendiri yang tidak dimiliki oleh kelas lain, kami boleh menambahkannya dengan mudah:
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");
   }
};
Dokumentasi Oracle mempunyai cadangan yang baik : "Gunakan kelas tanpa nama jika anda memerlukan kelas tempatan untuk kegunaan sekali sahaja." Kelas tanpa nama ialah kelas dalaman yang lengkap. Oleh itu, ia mempunyai akses kepada pembolehubah kelas luar, termasuk pembolehubah statik dan peribadi:
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;
           }
       };
   }
}
Mereka mempunyai sesuatu yang sama dengan kelas tempatan: mereka boleh dilihat hanya dalam kaedah yang ditakrifkan. Dalam contoh di atas, sebarang percubaan untuk mengakses objek errorModuledi luar kaedah main()akan gagal. Dan satu lagi batasan penting yang diwarisi oleh kelas tanpa nama daripada "nenek moyang" mereka - kelas dalaman: kelas tanpa nama tidak boleh mengandungi pembolehubah statik dan kaedah . Jika kita cuba membuat kaedah getCurrentErrorsCount()daripada contoh di atas statik, pengkompil akan membuang ralat:
//error! Inner classes cannot have static declarations
public static int getCurrentErrorsCount() {

   return currentErrorsCount;
}
Kami mendapat hasil yang sama jika kami cuba mengisytiharkan pembolehubah statik:
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!");
   }

};
Akhir sekali, saya boleh mengesyorkan anda video yang sangat baik mengenai topik kelas tanpa nama, di mana topik ini diterangkan semudah dan sejelas mungkin :)
Dan pelajaran kita hari ini telah berakhir! Dan walaupun kami telah membincangkan kumpulan terakhir kelas bersarang, kami belum selesai dengan topik ini lagi. Apakah yang akan kita pelajari seterusnya tentang kelas bersarang? Anda pasti akan mengetahuinya tidak lama lagi! :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION