CodeGym /Java blogg /Slumpmässig /Anonyma klasser
John Squirrels
Nivå
San Francisco

Anonyma klasser

Publicerad i gruppen
Hej! I dagens lektion kommer vi att fortsätta att undersöka ämnet kapslade klasser. Nu är det dags för den sista gruppen: anonyma inre klasser. Låt oss återgå till vårt diagram: Anonyma klasser - 2Precis som de lokala klasserna som vi pratade om i förra lektionen är anonyma klasser en slags inre klass... De har också flera likheter och skillnader. Men först, låt oss dyka in: varför exakt kallas de "anonyma"? För att svara på detta, överväg ett enkelt exempel. Tänk dig att vi har ett grundprogram som hela tiden är igång och gör något. Vi vill skapa ett övervakningssystem för detta program, som består av flera moduler. En modul kommer att spåra allmänna prestandaindikatorer och föra en logg. Den andra kommer att registrera och registrera fel i en fellogg. Den tredje kommer att spåra misstänkt aktivitet: till exempel obehörig åtkomstförsök och andra säkerhetsrelaterade saker. Eftersom alla tre modulerna i huvudsak ska starta i början av programmet och köras i bakgrunden,

public interface MonitoringSystem {
  
   public void startMonitoring();
}
3 betongklasser kommer att implementera 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 verkar som att allt är i sin ordning. Vi har ett ganska sammanhängande system som består av flera moduler. Var och en av dem har sitt eget beteende. Om vi ​​behöver nya moduler kan vi lägga till dem, eftersom vi har ett gränssnitt som är ganska enkelt att implementera. Men låt oss fundera på hur vårt övervakningssystem kommer att fungera. Anonyma klasser - 3I grund och botten behöver vi bara skapa 3 objekt — , , GeneralIndicatorMonitoringModuleErrorMonitoringModuleoch SecurityModuleanropa startMonitoring()metoden för vart och ett av dem. Det vill säga, allt vi behöver göra är att skapa 3 objekt och anropa 1 metod 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();
   }
}
Konsolutgång:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Och med så lite arbete har vi skrivit hela systemet: 3 klasser och ett gränssnitt! Och allt detta för att uppnå 6 rader kod. Å andra sidan, vilka är våra alternativ? Tja, det är inte särskilt coolt att vi skrev dessa "engångskurser". Men hur kan vi fixa detta? Här kommer anonyma inre klasser till vår räddning! Så här ser de ut i vårt fall:

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();
   }
}
Låt oss ta reda på vad som händer! Det ser ut som att vi skapar ett gränssnittsobjekt:

MonitoringSystem generalModule = new MonitoringSystem() {
   
@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
};
Men vi har länge vetat att vi inte kan skapa gränssnittsobjekt! Och så är det - det är omöjligt. Det är faktiskt inte det vi gör. När vi skriver:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
följande händer inuti Java-maskinen:
  1. En icke namngiven Java-klass skapas som implementerar MonitoringSystemgränssnittet.
  2. När kompilatorn ser en sådan klass, kräver den att du implementerar alla metoder för gränssnittet MonitoringSystem(vi gjorde detta 3 gånger).
  3. Ett objekt i denna klass skapas. Var uppmärksam på koden:

MonitoringSystem generalModule = new MonitoringSystem() {
   
};
Det finns ett semikolon i slutet! Det finns där av en anledning. Vi deklarerar samtidigt klassen (med hjälp av hängslen) och skapar en instans av den (med hjälp av ) ();. Vart och ett av våra tre objekt åsidosätter startMonitoring()metoden på sitt eget sätt. Slutligen kallar vi helt enkelt denna metod på var och en av dem:

generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Konsolutgång:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
Det är allt! Vi uppnådde vårt mål: vi skapade tre MonitoringSystemobjekt, åsidosatte en metod på tre olika sätt och kallade den tre gånger. Alla tre modulerna har anropats och körs. Samtidigt har strukturen på vårt program blivit mycket enklare! När allt kommer omkring kan klasserna GeneralIndicatorMonitoringModule, ErrorMonitoringModule, och SecurityModulenu tas bort helt från programmet! Vi behöver dem helt enkelt inte – vi gjorde ett bra jobb utan dem. Om var och en av våra anonyma klasser behöver något annat beteende, t.ex. sina egna specifika metoder som de andra inte har, kan vi enkelt lägga till 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 ger en bra rekommendation : "Använd [anonyma klasser] om du bara behöver använda en lokal klass en gång." En anonym klass är en fullvärdig inre klass. Följaktligen har den tillgång till variablerna för den externa klassen, inklusive statiska och privata 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 något gemensamt med lokala klasser: de är endast synliga i metoden där de deklareras. I exemplet ovan misslyckas alla försök att komma åt errorModuleobjektet utanför metoden. main()Och det finns ytterligare en viktig begränsning som anonyma klasser ärver från sina "förfäder" (inre klasser): en anonym klass kan inte innehålla statiska variabler och metoder . I exemplet ovan, om vi försöker göra getCurrentErrorCount()metoden statisk, kommer kompilatorn att generera ett fel:

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

   return currentErrorCount;
}
Vi får samma resultat om vi försöker deklarera 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!");
   }

};
Och vår lektion idag har tagit slut! Men även om vi har undersökt den sista gruppen kapslade klasser, har vi ännu inte avslutat detta ämne. Vad mer kommer vi att lära oss om kapslade klasser? Du kommer säkert att få reda på det snart! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION