CodeGym /Java Blog /Willekeurig /Statische geneste klassen
John Squirrels
Niveau 41
San Francisco

Statische geneste klassen

Gepubliceerd in de groep Willekeurig
Hoi! We blijven het onderwerp van geneste klassen in Java onderzoeken. In de laatste oefening hebben we het gehad over niet-statische geneste klassen, ook wel innerlijke klassen genoemd. Statische geneste klassen - 1Vandaag gaan we verder met een andere groep klassen. We zullen statische geneste klassen overwegen. Statische geneste klassen - 3Hoe verschillen ze van andere klassen? Bij het declareren van dit soort klassen gebruiken we het statische trefwoord, waarmee u al bekend bent:

public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {
      
       public static int getMaxPassengersCount() {
          
           return maxPassengersCount;
       }
   }
}
Statische geneste klassen - 4In dit voorbeeld hebben we de Boeing737buitenste klasse, die een vliegtuig van dit type vertegenwoordigt. Het heeft een constructor met één parameter: het fabricagejaar ( int manufactureYear). Er is ook één statische variabele: het maximum aantal passagiers ( int maxPassengersCount). Het heeft dezelfde waarde voor alle vlakken van hetzelfde model, dus we hebben maar één instantie nodig. Bovendien heeft het een statische geneste klasse: Drawing(die de technische blauwdrukken van het vliegtuig vertegenwoordigt). We gebruiken deze klasse om alle officiële informatie over het vliegtuig in te kapselen. In ons voorbeeld hebben we deze klasse voor de eenvoud beperkt tot het fabricagejaar, maar deze klasse kan veel andere informatie bevatten. Statische geneste klassen - 5Zoals we in de vorige les zeiden, verbetert het creëren van zo'n geneste klasse de inkapseling en draagt ​​het bij aan een meer realistische abstractie. Wat is het verschil tussen statische en niet-statische geneste klassen? 1. Een object van de statische Drawingklasse slaat geen verwijzing op naar een specifieke instantie van de buitenste klasse. Denk aan het voorbeeld van de fiets uit de vorige les:

public class Bicycle {

   private String model;
   private int maxWeight;

   public Bicycle(String model, int maxWeight) {
       this.model = model;
       this.maxWeight = maxWeight;
   }
  
   public void start() {
       System.out.println("Let's go!");
   }

   public class Handlebar {

       public void right() {
           System.out.println("Steer right!");
       }

       public void left() {

           System.out.println("Steer left!");
       }
   }

}
In die les hebben we het gehad over het feit dat elke instantie van de Handlebarinnerlijke klasse, onmerkbaar voor ons, een verwijzing doorgeeft aan de instantie van de Bicyclebuitenste klasse. Zonder een instantie van de buitenste klasse zou een object van de binnenste klasse eenvoudigweg niet kunnen bestaan. Voor statische geneste klassen is dit niet het geval. Een object van een statische geneste klasse kan volledig op zichzelf bestaan. In dit opzicht zijn statische klassen meer "onafhankelijk" dan niet-statisch. Het enige dat u moet weten, is dat u bij het maken van een dergelijk object de naam van de buitenste klasse moet specificeren:

public class Main {

   public static void main(String[] args) {

       Boeing737.Drawing drawing1 = new Boeing737.Drawing();
       Boeing737.Drawing drawing2 = new Boeing737.Drawing();
   }
}
Waarom hebben we de klas statisch gemaakt Drawingterwijl we in de laatste les deSeatklasse (staat voor het fietsstoeltje) niet-statisch? Laten we, net als de vorige keer, een beetje "filosofie" toevoegen om het voorbeeld te begrijpen :) In tegenstelling tot een fietsstoeltje is het concept van een technische tekening niet strikt gebonden aan het concept van een vliegtuig. Zonder fiets zou een apart fietsstoeltje meestal zinloos zijn (hoewel niet altijd, daar hebben we het in de vorige les over gehad). Het concept van een technische tekening is op zichzelf logisch. Het kan bijvoorbeeld nuttig zijn voor ingenieurs die vliegtuigonderhoud plannen. Het vliegtuig is niet nodig om het plan te maken en kan overal staan. Alleen de technische tekening is nodig. Bovendien zullen alle vliegtuigen van hetzelfde model dezelfde ingenieurstekening hebben, dus er is niet zo'n hechte relatie als bij een fietsstoeltje. Daarom eenDrawingobject heeft geen verwijzing naar een specifiek vliegtuigobject nodig. 2. Verschillende toegang tot de variabelen en methoden van de buitenste klasse. Een statische geneste klasse heeft alleen toegang tot de statische velden van een buitenste klasse. In ons voorbeeld Drawingheeft de klasse een getMaxPassengersCount()methode die de waarde van de statische variabele van de buitenste klasse retourneert maxPassengersCount. We kunnen echter geen getManufactureYear()methode in de Drawingklasse maken om de waarde van te retourneren manufactureYear. De variabele is immers manufactureYearniet-statisch, wat betekent dat hij tot een specifieke instantie van Boeing737. En zoals we al hebben ontdekt, kan het object van de buitenste klasse in het geval van statische geneste klassen gemakkelijk afwezig zijn. Vandaar de beperking :) Het maakt niet uit welke toegangsmodificator een statische variabele heeft in de buitenste klasse. Zelfs als het isprivate, heeft een statische geneste klasse nog steeds toegang. Al het bovenstaande is niet alleen van toepassing op toegang tot statische variabelen, maar ook op statische methoden. BELANGRIJK! Bij de declaratie van een innerlijke klasse staticbetekent het sleutelwoord niet dat u maar één object kunt maken. Verwar objecten niet met variabelen. Als we het hebben over statische variabelen, dan bestaat er inderdaad een enkele instantie van een statische klassevariabele, bijvoorbeeld maxPassangersCount. Maar wanneer staticwordt toegepast op een geneste klasse, betekent dit alleen dat de objecten geen verwijzingen bevatten naar objecten van de buitenste klasse. En we kunnen zoveel objecten zelf maken als we willen:

public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

       private int id;

       public Drawing(int id) {
           this.id = id;
       }

       public static int getPassengersCount() {

           return maxPassengersCount;
       }

       @Override
       public String toString() {
           return "Drawing{" +
                   "id=" + id +
                   '}';
       }

       public static void main(String[] args) {

           for (int i = 1; i < 6; i++) {

               Boeing737.Drawing drawing = new Boeing737.Drawing(i);
               System.out.println(drawing);
           }
       }
   }
}
We hebben de main()methode rechtstreeks in de geneste klasse gedeclareerd (hier is geen speciale reden voor - alleen om u te laten weten dat dit mogelijk is), en hebben 5 Drawingobjecten gemaakt. Ondanks het feit dat we geen enkel object van de buitenste klasse hebben. Zoals u kunt zien, heeft dit geen problemen opgeleverd :) Console-uitvoer:

Drawing{id=1} 
Drawing{id=2} 
Drawing{id=3} 
Drawing{id=4} 
Drawing{id=5}
En daarmee is onze les afgelopen! Voor het geval dat, laat ik je een link achter naar het gedeelte erover in de Oracle-documentatie . Als er nog steeds iets onduidelijk is, lees het dan. Nu is het tijd voor mij om een ​​aantal taken op te lossen! :)
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION