Hei! Vi fortsetter å utforske temaet nestede klasser i Java. I den siste øvelsen snakket vi om ikke-statiske nestede klasser, som også er kjent som indre klasser. I dag går vi videre til en annen gruppe klasser. Vi vil vurdere statiske nestede klasser. Hvordan er de forskjellige fra andre klasser? Når vi erklærer denne typen klasse, bruker vi det statiske nøkkelordet, som du allerede er kjent med:
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;
}
}
}
I dette eksemplet har vi den Boeing737
ytre klassen, som representerer et fly av denne typen. Den har en konstruktør med én parameter: produksjonsåret ( int manufactureYear
). Det er også én statisk variabel: maksimalt antall passasjerer ( int maxPassengersCount
). Det vil ha samme verdi for alle fly av samme modell, så vi trenger bare én forekomst. I tillegg har den en statisk nestet klasse: Drawing
(representerer flyets tekniske tegninger). Vi bruker denne klassen til å kapsle inn all offisiell informasjon om flyet. I vårt eksempel har vi for enkelhets skyld begrenset denne klassen til produksjonsåret, men den kan inneholde mye annen informasjon. Som vi sa i forrige leksjon, forbedrer å lage en slik nestet klasse innkapsling og bidrar til en mer realistisk abstraksjon. Hva er forskjellen mellom statiske og ikke-statiske nestede klasser? 1. Et objekt av den statiske Drawing
klassen lagrer ikke en referanse til en spesifikk forekomst av den ytre klassen. Husk sykkeleksemplet fra forrige leksjon:
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 leksjonen snakket vi om det faktum at hver instans av den Handlebar
indre klassen, umerkelig for oss, sender en referanse til instansen til den Bicycle
ytre klassen. Uten en forekomst av den ytre klassen, kunne et objekt av den indre klassen rett og slett ikke eksistere. For statiske nestede klasser er ikke dette tilfellet. Et objekt av en statisk nestet klasse er helt i stand til å eksistere på egen hånd. I denne forbindelse er statiske klasser mer "uavhengige" enn ikke-statiske. Det eneste du trenger å vite er at når du oppretter et slikt objekt, må du spesifisere navnet på den ytre klassen:
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 forrige leksjon lagetSeat
klasse (som representerer sykkelsetet) ikke-statisk? Som forrige gang, la oss legge til litt "filosofi" for å forstå eksempelet :) I motsetning til et sykkelsete, er ikke konseptet med en ingeniørtegning stivt knyttet til konseptet om et fly. Uten sykkel ville et eget sykkelseteobjekt oftest vært meningsløst (men ikke alltid, vi snakket om dette i forrige leksjon). Konseptet med en ingeniørtegning gir mening i seg selv. Det kan for eksempel være nyttig for ingeniører som planlegger flyvedlikehold. Flyet er ikke nødvendig for å lage planen og kan plasseres hvor som helst. Kun ingeniørtegningen er nødvendig. I tillegg vil alle fly av samme modell ha samme ingeniørtegning, så det er ikke et så tett forhold som det finnes med et sykkelsete. Derfor, aDrawing
objektet trenger ikke en referanse til et spesifikt flyobjekt. 2. Ulik tilgang til variablene og metodene til den ytre klassen. En statisk nestet klasse kan bare få tilgang til de statiske feltene til en ytre klasse. I vårt eksempel Drawing
har klassen en getMaxPassengersCount()
metode som returnerer verdien av den statiske maxPassengersCount
variabelen til den ytre klassen. Vi kan imidlertid ikke opprette en getManufactureYear()
metode i Drawing
klassen for å returnere verdien av manufactureYear
. Tross alt manufactureYear
er variabelen ikke-statisk, noe som betyr at den må tilhøre en spesifikk forekomst av Boeing737
. Og som vi allerede har oppdaget, i tilfelle av statiske nestede klasser, kan objektet til den ytre klassen lett være fraværende. Derav begrensningen :) Det spiller ingen rolle hvilken tilgangsmodifikator en statisk variabel har i den ytre klassen. Selv om det er detprivate
, vil en statisk nestet klasse fortsatt ha tilgang. Alt det ovennevnte gjelder ikke bare tilgang til statiske variabler, men også statiske metoder. VIKTIG! I erklæringen om en indre klasse static
betyr ikke nøkkelordet at du bare kan lage ett objekt. Ikke forveksle objekter med variabler. Hvis vi snakker om statiske variabler, så, ja, det eksisterer en enkelt forekomst av en statisk klassevariabel, for eksempel maxPassangersCount
. Men når static
den brukes på en nestet klasse, betyr det bare at dens objekter ikke inneholder referanser til objekter i den ytre klassen. Og vi kan lage så mange av objektene selv 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ærte main()
metoden direkte i den nestede klassen (det er ingen spesiell grunn til dette - bare for å fortelle deg at dette er mulig), og opprettet 5 Drawing
objekter. Til tross for at vi ikke har et eneste objekt av den ytre klassen. Som du kan se, skapte ikke dette noen problemer :) Konsollutgang:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
Og det avslutter leksjonen vår! Bare i tilfelle gir jeg deg en lenke til delen om dem i Oracle-dokumentasjonen . Hvis noe fortsatt er uklart, les det. Nå er det på tide for meg å løse et par oppgaver! :)
GO TO FULL VERSION