CodeGym /Java Blog /Random /Anonymous na klase
John Squirrels
Antas
San Francisco

Anonymous na klase

Nai-publish sa grupo
Hi! Sa aralin ngayon, patuloy nating susuriin ang paksa ng mga nested na klase. Ngayon ay oras na para sa huling grupo: anonymous na mga panloob na klase. Bumalik tayo sa aming diagram: Mga hindi kilalang klase - 2Tulad ng mga lokal na klase na pinag-usapan natin sa nakaraang aralin, ang mga anonymous na klase ay isang uri ng panloob na klase... Mayroon din silang ilang pagkakatulad at pagkakaiba. Ngunit una, sumisid tayo: bakit nga ba sila tinatawag na "anonymous"? Upang masagot ito, isaalang-alang ang isang simpleng halimbawa. Isipin na mayroon tayong pangunahing programa na patuloy na tumatakbo at gumagawa ng isang bagay. Nais naming lumikha ng isang sistema ng pagsubaybay para sa programang ito, na binubuo ng ilang mga module. Susubaybayan ng isang module ang mga pangkalahatang tagapagpahiwatig ng pagganap at magpanatili ng isang log. Ang pangalawa ay magrerehistro at magtatala ng mga error sa isang log ng error. Susubaybayan ng ikatlo ang kahina-hinalang aktibidad: halimbawa, mga hindi awtorisadong pagtatangka sa pag-access at iba pang mga bagay na nauugnay sa seguridad. Dahil ang lahat ng tatlong mga module ay dapat, sa esensya, magsimula lamang sa simula ng programa at tumakbo sa background,

public interface MonitoringSystem {
  
   public void startMonitoring();
}
3 kongkretong klase ang magpapatupad nito:

public class GeneralIndicatorMonitoringModule implements MonitoringSystem {
   
@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor errors!");
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor security!");
   }
}
Mukhang maayos na ang lahat. Mayroon kaming medyo magkakaugnay na sistema na binubuo ng ilang mga module. Ang bawat isa sa kanila ay may sariling pag-uugali. Kung kailangan namin ng mga bagong module, maaari naming idagdag ang mga ito, dahil mayroon kaming isang interface na medyo madaling ipatupad. Ngunit isipin natin kung paano gagana ang ating monitoring system. Mga hindi kilalang klase - 3Karaniwan, kailangan lang nating lumikha ng 3 bagay — GeneralIndicatorMonitoringModule, ErrorMonitoringModule, SecurityModule— at tawagan ang startMonitoring()pamamaraan sa bawat isa sa kanila. Ibig sabihin, ang kailangan lang nating gawin ay lumikha ng 3 bagay at tumawag ng 1 paraan sa kanila.

public class Main {

   public static void main(String[] args) {

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

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Output ng console:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
At sa kaunting gawain, naisulat na namin ang buong sistema: 3 klase at isang interface! At lahat ng ito upang makamit ang 6 na linya ng code. Sa kabilang banda, ano ang aming mga pagpipilian? Well, hindi masyadong cool na isinulat namin ang "isang beses" na mga klase. Ngunit paano natin ito maaayos? Narito ang mga hindi kilalang panloob na klase ay sumagip sa amin! Narito ang hitsura nila sa aming kaso:

public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor general indicators!");
           }
       };

       

MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor errors!");
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor security!");
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Alamin natin kung ano ang nangyayari! Mukhang gumagawa kami ng interface object:

MonitoringSystem generalModule = new MonitoringSystem() {
   
@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
};
Ngunit matagal na naming alam na hindi kami makakalikha ng mga bagay sa interface! At ganoon nga—imposible. Sa katunayan, hindi iyon ang ginagawa namin. Kapag sumulat tayo:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
ang sumusunod ay nangyayari sa loob ng Java machine:
  1. Isang hindi pinangalanang Java class ang nilikha na nagpapatupad ng MonitoringSysteminterface.
  2. Kapag nakita ng compiler ang ganitong klase, kailangan mong ipatupad ang lahat ng mga pamamaraan ng MonitoringSysteminterface (ginawa namin ito ng 3 beses).
  3. Isang bagay ng klase na ito ay nilikha. Bigyang-pansin ang code:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
May semicolon sa dulo! Ito ay naroroon para sa isang dahilan. Sabay-sabay naming idineklara ang klase (gamit ang mga kulot na braces) at lumikha ng isang instance nito (gamit ang ();). Ang bawat isa sa aming tatlong bagay ay na-override ang startMonitoring()pamamaraan sa sarili nitong paraan. Sa wakas, tinatawag lang namin ang pamamaraang ito sa bawat isa sa kanila:

generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Output ng console:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Ayan yun! Nakamit namin ang aming layunin: lumikha kami ng tatlong MonitoringSystembagay, na-overrode ang isang pamamaraan sa tatlong magkakaibang paraan, at tinawag itong tatlong beses. Ang lahat ng tatlong mga module ay matagumpay na natawag at tumatakbo. Kasabay nito, ang istraktura ng aming programa ay naging mas simple! Pagkatapos ng lahat, ang GeneralIndicatorMonitoringModule, ErrorMonitoringModule, at SecurityModulemga klase ay maaari na ngayong ganap na alisin sa programa! Hindi lang namin sila kailangan — gumawa kami ng mahusay na trabaho nang wala sila. Kung ang bawat isa sa aming mga hindi kilalang klase ay nangangailangan ng ilang magkakaibang pag-uugali, hal. sarili nitong mga partikular na pamamaraan na wala sa iba, madali naming maidaragdag ang mga ito:

MonitoringSystem generalModule = new MonitoringSystem() {
  
   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
  
   public void someSpecificMethod() {

       System.out.println("Specific method only for the first module");
   }
};
Ang dokumentasyon ng Oracle ay nagbibigay ng magandang rekomendasyon : "Gumamit ng [mga hindi kilalang klase] kung kailangan mong gumamit ng lokal na klase nang isang beses lang." Ang hindi kilalang klase ay isang ganap na panloob na klase. Alinsunod dito, mayroon itong access sa mga variable ng panlabas na klase, kabilang ang mga static at pribadong variable:

public class Main {

   private static int currentErrorCount = 23;

   public static void main(String[] args) {

       MonitoringSystem errorModule = new MonitoringSystem() {
          
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor errors!");
           }

           public int getCurrentErrorCount() {

               return currentErrorCount;
           }
       };
   }
}
Mayroon silang isang bagay na karaniwan sa mga lokal na klase: makikita lamang ang mga ito sa loob ng pamamaraan kung saan idineklara ang mga ito. Sa halimbawa sa itaas, ang anumang pagtatangka na i-access ang errorModulebagay sa labas ng main()pamamaraan ay mabibigo. At may isa pang mahalagang limitasyon na minana ng mga anonymous na klase mula sa kanilang "mga ninuno" (mga panloob na klase): hindi maaaring maglaman ang isang anonymous na klase ng mga static na variable at pamamaraan . Sa halimbawa sa itaas, kung susubukan naming gawing getCurrentErrorCount()static ang pamamaraan, bubuo ng error ang compiler:

// Error! Inner classes cannot have static declarations
public static int getCurrentErrorCount() {

   return currentErrorCount;
}
Nakukuha namin ang parehong resulta kung susubukan naming magdeklara ng isang static na variable:

MonitoringSystem errorModule = new MonitoringSystem() {

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

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor errors!");
   }

};
At ang ating aralin ngayon ay natapos na! Ngunit kahit na naimbestigahan na namin ang huling pangkat ng mga nested na klase, hindi pa namin natapos ang paksang ito. Ano pa ang matututunan natin tungkol sa mga nested na klase? Tiyak na malalaman mo sa lalong madaling panahon! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION