CodeGym /Java-blogg /Tilfeldig /Anonyme klasser
John Squirrels
Nivå
San Francisco

Anonyme klasser

Publisert i gruppen
Hei! I dagens leksjon vil vi fortsette å undersøke temaet nestede klasser. Nå er det tid for siste gruppe: anonyme indre klasser. La oss gå tilbake til diagrammet vårt: Anonyme klasser - 2I likhet med de lokale klassene som vi snakket om i forrige leksjon, er anonyme klasser en slags indre klasse... De har også flere likheter og forskjeller. Men først, la oss dykke inn: hvorfor akkurat kalles de "anonyme"? For å svare på dette, tenk på et enkelt eksempel. Tenk deg at vi har et basisprogram som hele tiden kjører og gjør noe. Vi ønsker å lage et overvåkingssystem for dette programmet, som består av flere moduler. Én modul vil spore generelle ytelsesindikatorer og opprettholde en logg. Den andre vil registrere og registrere feil i en feillogg. Den tredje vil spore mistenkelig aktivitet: for eksempel uautoriserte tilgangsforsøk og andre sikkerhetsrelaterte ting. Fordi alle tre modulene i hovedsak skal starte i begynnelsen av programmet og kjøre i bakgrunnen,

public interface MonitoringSystem {
  
   public void startMonitoring();
}
3 betongklasser 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 ut til at alt er i orden. Vi har et ganske sammenhengende system som består av flere moduler. Hver av dem har sin egen oppførsel. Hvis vi trenger nye moduler, kan vi legge dem til, fordi vi har et grensesnitt som er ganske enkelt å implementere. Men la oss tenke på hvordan overvåkingssystemet vårt vil fungere. Anonyme klasser - 3I utgangspunktet trenger vi bare å lage 3 objekter — GeneralIndicatorMonitoringModule, ErrorMonitoringModule, SecurityModule— og kalle startMonitoring()metoden på hver av dem. Det vil si at alt vi trenger å gjøre er å lage 3 objekter og kalle 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();
   }
}
Konsoll utgang:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Og med så lite arbeid har vi skrevet hele systemet: 3 klasser og ett grensesnitt! Og alt dette for å oppnå 6 linjer med kode. På den annen side, hva er alternativene våre? Vel, det er ikke veldig kult at vi skrev disse "engangstimene". Men hvordan kan vi fikse dette? Her kommer anonyme indre klasser oss til unnsetning! Slik ser de ut i vårt tilfelle:

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();
   }
}
La oss finne ut hva som skjer! Det ser ut som om vi lager et grensesnittobjekt:

MonitoringSystem generalModule = new MonitoringSystem() {
   
@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
};
Men vi har lenge visst at vi ikke kan lage grensesnittobjekter! Og slik er det - det er umulig. Det er faktisk ikke det vi gjør. Når vi skriver:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
følgende skjer inne i Java-maskinen:
  1. Det opprettes en navnløs Java-klasse som implementerer grensesnittet MonitoringSystem.
  2. Når kompilatoren ser en slik klasse, krever det at du implementerer alle metodene til grensesnittet MonitoringSystem(vi gjorde dette 3 ganger).
  3. Ett objekt av denne klassen er opprettet. Vær oppmerksom på koden:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
Det er et semikolon på slutten! Det er der av en grunn. Vi erklærer klassen samtidig (ved hjelp av krøllete klammeparenteser) og lager en forekomst av den (ved hjelp av ();). Hvert av våre tre objekter overstyrer startMonitoring()metoden på sin egen måte. Til slutt kaller vi bare denne metoden på hver av dem:

generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Konsoll utgang:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Det er det! Vi nådde målet vårt: vi laget tre MonitoringSystemobjekter, overstyrte en metode på tre forskjellige måter og kalte den tre ganger. Alle tre modulene har blitt kalt og kjører. Samtidig har strukturen på programmet vårt blitt mye enklere! Tross alt kan GeneralIndicatorMonitoringModule, ErrorMonitoringModule, og SecurityModuleklassene nå fjernes helt fra programmet! Vi trenger dem rett og slett ikke - vi gjorde en god jobb uten dem. Hvis hver av våre anonyme klasser trenger en annen oppførsel, for eksempel sine egne spesifikke metoder som de andre ikke har, kan vi enkelt legge dem til:

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-dokumentasjonen gir en god anbefaling : "Bruk [anonyme klasser] hvis du trenger å bruke en lokal klasse bare én gang." En anonym klasse er en fullverdig indre klasse. Følgelig har den tilgang til variablene til den eksterne klassen, inkludert 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 noe til felles med lokale klasser: de er kun synlige innenfor metoden de er deklarert i. I eksemplet ovenfor vil alle forsøk på å få tilgang til errorModuleobjektet utenfor main()metoden mislykkes. Og det er enda en viktig begrensning som anonyme klasser arver fra sine "forfedre" (indre klasser): en anonym klasse kan ikke inneholde statiske variabler og metoder . I eksemplet ovenfor, hvis vi prøver å gjøre getCurrentErrorCount()metoden statisk, vil kompilatoren generere en feil:

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

   return currentErrorCount;
}
Vi får samme resultat hvis vi prøver å 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 leksjonen vår i dag er over! Men selv om vi har undersøkt den siste gruppen av nestede klasser, er vi ennå ikke ferdige med dette emnet. Hva mer vil vi lære om nestede klasser? Du vil garantert finne ut av det snart! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION