CodeGym /Java blog /Tilfældig /Anonyme klasser
John Squirrels
Niveau
San Francisco

Anonyme klasser

Udgivet i gruppen
Hej! I dagens lektion vil vi fortsætte med at undersøge emnet indlejrede klasser. Nu er det tid til den sidste gruppe: anonyme indre klasser. Lad os vende tilbage til vores diagram: Anonyme klasser - 2Ligesom de lokale klasser, som vi talte om i sidste lektion, er anonyme klasser en slags indre klasse... De har også flere ligheder og forskelle. Men først, lad os dykke ned: hvorfor præcist kaldes de "anonyme"? For at besvare dette, overvej et simpelt eksempel. Forestil dig, at vi har et grundprogram, der konstant kører og laver noget. Vi ønsker at skabe et overvågningssystem for dette program, der består af flere moduler. Et modul vil spore generelle indikatorer for ydeevne og vedligeholde en log. Den anden vil registrere og registrere fejl i en fejllog. Den tredje vil spore mistænkelig aktivitet: for eksempel uautoriseret adgangsforsøg og andre sikkerhedsrelaterede ting. Fordi alle tre moduler i det væsentlige skal starte i begyndelsen af ​​programmet og køre i baggrunden,

public interface MonitoringSystem {
  
   public void startMonitoring();
}
3 betonklasser vil implementere det:

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!");
   }
}
Det ser ud til, at alt er i orden. Vi har et ret sammenhængende system, der består af flere moduler. Hver af dem har sin egen adfærd. Har vi brug for nye moduler, kan vi tilføje dem, for vi har en grænseflade, der er ret nem at implementere. Men lad os tænke på, hvordan vores overvågningssystem vil fungere. Anonyme klasser - 3Grundlæggende skal vi bare oprette 3 objekter — GeneralIndicatorMonitoringModule, ErrorMonitoringModule, SecurityModule— og kalde startMonitoring()metoden på hver af dem. Det vil sige, alt hvad vi skal gøre er at oprette 3 objekter og kalde 1 metode på dem.

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();
   }
}
Konsoludgang:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Og med så lidt arbejde har vi skrevet hele systemet: 3 klasser og en grænseflade! Og alt dette for at opnå 6 linjer kode. På den anden side, hvad er vores muligheder? Nå, det er ikke særlig fedt, at vi skrev disse "engangstimer". Men hvordan kan vi fikse dette? Her kommer anonyme indre klasser os til undsætning! Sådan ser de ud i vores tilfælde:

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();
   }
}
Lad os finde ud af, hvad der foregår! Det ser ud til, at vi opretter et grænsefladeobjekt:

MonitoringSystem generalModule = new MonitoringSystem() {
   
@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
};
Men vi har længe vidst, at vi ikke kan skabe grænsefladeobjekter! Og sådan er det - det er umuligt. Det er faktisk ikke det, vi gør. Når vi skriver:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
følgende sker inde i Java-maskinen:
  1. Der oprettes en unavngiven Java-klasse, der implementerer MonitoringSystemgrænsefladen.
  2. Når compileren ser sådan en klasse, kræver det, at du implementerer alle grænsefladens metoder MonitoringSystem(vi gjorde dette 3 gange).
  3. Et objekt af denne klasse er oprettet. Vær opmærksom på koden:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
Der er et semikolon i slutningen! Det er der af en grund. Vi erklærer samtidig klassen (ved hjælp af krøllede klammeparenteser) og opretter en forekomst af den (ved hjælp af ();). Hvert af vores tre objekter tilsidesætter startMonitoring()metoden på sin egen måde. Til sidst kalder vi blot denne metode på hver af dem:

generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Konsoludgang:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Det er det! Vi nåede vores mål: vi skabte tre MonitoringSystemobjekter, tilsidesatte en metode på tre forskellige måder og kaldte den tre gange. Alle tre moduler er blevet kaldt og kører. Samtidig er opbygningen af ​​vores program blevet meget enklere! Når alt kommer til alt, kan GeneralIndicatorMonitoringModule, ErrorMonitoringModule, og SecurityModuleklasserne nu fjernes helt fra programmet! Vi har simpelthen ikke brug for dem - vi gjorde et godt stykke arbejde uden dem. Hvis hver af vores anonyme klasser har brug for en anden adfærd, f.eks. deres egne specifikke metoder, som de andre ikke har, kan vi nemt tilføje dem:

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");
   }
};
Oracle-dokumentationen giver en god anbefaling : "Brug [anonyme klasser], hvis du kun skal bruge en lokal klasse én gang." En anonym klasse er en fuldgyldig indre klasse. Følgelig har den adgang til variablerne i den eksterne klasse, herunder statiske og private variabler:

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;
           }
       };
   }
}
De har noget til fælles med lokale klasser: de er kun synlige i den metode, hvor de er deklareret. I eksemplet ovenfor vil ethvert forsøg på at få adgang til objektet errorModuleuden for main()metoden mislykkes. Og der er endnu en vigtig begrænsning, som anonyme klasser arver fra deres "forfædre" (indre klasser): en anonym klasse kan ikke indeholde statiske variabler og metoder . I eksemplet ovenfor, hvis vi forsøger at gøre getCurrentErrorCount()metoden statisk, vil compileren generere en fejl:

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

   return currentErrorCount;
}
Vi får det samme resultat, hvis vi forsøger at erklære en statisk variabel:

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!");
   }

};
Og vores lektion i dag er slut! Men selvom vi har undersøgt den sidste gruppe af indlejrede klasser, er vi endnu ikke færdige med dette emne. Hvad mere vil vi lære om indlejrede klasser? Du vil helt sikkert finde ud af det snart! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION