Hej! Vi fortsætter med at udforske emnet indlejrede klasser i Java. I den sidste øvelse talte vi om ikke-statiske indlejrede klasser, som også er kendt som indre klasser.
I dag går vi videre til en anden gruppe af klasser. Vi vil overveje statiske indlejrede klasser.
Hvordan adskiller de sig fra andre klasser? Når vi erklærer denne slags klasse, bruger vi det statiske nøgleord, som du allerede kender:
I dette eksempel har vi den
Som vi sagde i sidste lektion, forbedrer oprettelse af sådan en indlejret klasse indkapslingen og bidrager til en mere realistisk abstraktion. Hvad er forskellen mellem statiske og ikke-statiske indlejrede klasser? 1. Et objekt af den statiske


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;
}
}
}

Boeing737
ydre klasse, som repræsenterer et fly af denne type. Den har en konstruktør med én parameter: fremstillingsåret ( int manufactureYear
). Der er også en statisk variabel: det maksimale antal passagerer ( int maxPassengersCount
). Det vil have samme værdi for alle fly af samme model, så vi behøver kun én instans. Derudover har den en statisk indlejret klasse: Drawing
(repræsenterer flyets tekniske tegninger). Vi bruger denne klasse til at indkapsle al den officielle information om flyet. I vores eksempel har vi for overskuelighedens skyld begrænset denne klasse til fremstillingsåret, men den kan indeholde mange andre oplysninger. 
Drawing
klasse gemmer ikke en reference til en specifik instans af den ydre klasse. Husk cykeleksemplet fra sidste lektion:
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!");
}
}
}
I den lektion talte vi om det faktum, at hver instans af den Handlebar
indre klasse, umærkeligt for os, videregiver en henvisning til instansen af den Bicycle
ydre klasse. Uden en instans af den ydre klasse kunne et objekt af den indre klasse simpelthen ikke eksistere. For statiske indlejrede klasser er dette ikke tilfældet. Et objekt af en statisk indlejret klasse er fuldstændig i stand til at eksistere alene. I denne henseende er statiske klasser mere "uafhængige" end ikke-statiske. Det eneste du behøver at vide er, at når du opretter et sådant objekt, skal du angive navnet på den ydre klasse:
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
Hvorfor gjorde vi Drawing
klassen statisk, da vi i sidste lektion lavede denSeat
klasse (der repræsenterer cykelsædet) ikke-statisk? Lad os ligesom sidste gang tilføje lidt "filosofi" for at forstå eksemplet :) I modsætning til et cykelsæde er begrebet en ingeniørtegning ikke stift bundet til begrebet et fly. Uden en cykel ville et separat cykelsædeobjekt oftest være meningsløst (dog ikke altid, det talte vi om i sidste lektion). Konceptet med en ingeniørtegning giver mening i sig selv. For eksempel kan det være nyttigt for ingeniører, der planlægger vedligeholdelse af fly. Flyet er ikke nødvendigt for at lave planen og kan placeres hvor som helst. Kun ingeniørtegningen er nødvendig. Derudover vil alle fly af samme model have samme ingeniørtegning, så der er ikke et så stramt forhold, som der er til et cykelsæde. Derfor, enDrawing
objekt behøver ikke en reference til et specifikt flyobjekt. 2. Forskellig adgang til den ydre klasses variabler og metoder. En statisk indlejret klasse kan kun få adgang til de statiske felter i en ydre klasse. I vores eksempel Drawing
har klassen en getMaxPassengersCount()
metode, der returnerer værdien af den statiske maxPassengersCount
variabel i den ydre klasse. Vi kan dog ikke oprette en getManufactureYear()
metode i Drawing
klassen til at returnere værdien af manufactureYear
. Variablen er jo manufactureYear
ikke-statisk, hvilket betyder, at den skal tilhøre en specifik instans af Boeing737
. Og som vi allerede har opdaget, i tilfælde af statiske indlejrede klasser, kan objektet for den ydre klasse let være fraværende. Derfor begrænsningen :) Det er lige meget, hvilken adgangsmodifikator en statisk variabel har i den ydre klasse. Også selvom det erprivate
, vil en statisk indlejret klasse stadig have adgang. Alt ovenstående gælder ikke kun for adgang til statiske variable, men også for statiske metoder. VIGTIG! I erklæringen af en indre klasse static
betyder nøgleordet ikke, at du kun kan oprette ét objekt. Forveksle ikke objekter med variable. Hvis vi taler om statiske variable, så, ja, der eksisterer en enkelt forekomst af en statisk klassevariabel, for eksempel maxPassangersCount
. Men når static
den anvendes på en indlejret klasse, betyder det kun, at dens objekter ikke indeholder referencer til objekter i den ydre klasse. Og vi kan selv skabe så mange af objekterne, som vi vil:
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);
}
}
}
}
Vi erklærede main()
metoden direkte i den indlejrede klasse (der er ingen særlig grund til dette - kun for at lade dig vide, at dette er muligt), og oprettede 5 Drawing
objekter. På trods af at vi ikke har et eneste objekt af den ydre klasse. Som du kan se, skabte dette ingen problemer :) Konsoloutput:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
Og det afslutter vores lektion! For en sikkerheds skyld efterlader jeg dig et link til afsnittet om dem i Oracle-dokumentationen . Hvis noget stadig er uklart, så læs det. Nu er det tid for mig at løse et par opgaver! :)
GO TO FULL VERSION