CodeGym /Blog Java /Random-PL /Statyczne klasy zagnieżdżone
Autor
John Selawsky
Senior Java Developer and Tutor at LearningTree

Statyczne klasy zagnieżdżone

Opublikowano w grupie Random-PL
Cześć! Kontynuujemy eksplorację tematu klas zagnieżdżonych w Javie. W ostatnim ćwiczeniu mówiliśmy o niestatycznych klasach zagnieżdżonych, które są również nazywane klasami wewnętrznymi. Statyczne klasy zagnieżdżone — 1Dzisiaj przejdziemy do innej grupy klas. Rozważymy statyczne klasy zagnieżdżone. Statyczne klasy zagnieżdżone - 3Czym różnią się od innych klas? Deklarując tego rodzaju klasę, używamy słowa kluczowego static, które już znasz:

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;
       }
   }
}
Statyczne klasy zagnieżdżone - 4W tym przykładzie mamy Boeing737klasę zewnętrzną, która reprezentuje samolot tego typu. Posiada konstruktor z jednym parametrem: rokiem produkcji ( int manufactureYear). Jest też jedna zmienna statyczna: maksymalna liczba pasażerów ( int maxPassengersCount). Będzie miał tę samą wartość dla wszystkich płaszczyzn tego samego modelu, więc potrzebujemy tylko jednej instancji. Dodatkowo ma statyczną zagnieżdżoną klasę: Drawing(reprezentującą plany inżynieryjne samolotu). Używamy tej klasy do hermetyzacji wszystkich oficjalnych informacji o samolocie. W naszym przykładzie dla uproszczenia ograniczyliśmy tę klasę do roku produkcji, ale może ona zawierać wiele innych informacji. Statyczne klasy zagnieżdżone - 5Jak powiedzieliśmy w poprzedniej lekcji, utworzenie takiej zagnieżdżonej klasy poprawia enkapsulację i przyczynia się do bardziej realistycznej abstrakcji. Jaka jest różnica między statycznymi i niestatycznymi klasami zagnieżdżonymi? 1. Obiekt klasy statycznej Drawingnie przechowuje odniesienia do konkretnej instancji klasy zewnętrznej. Zapamiętaj przykład roweru z ostatniej lekcji:

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!");
       }
   }

}
W tej lekcji mówiliśmy o tym, że każda instancja klasy Handlebarwewnętrznej, w sposób dla nas niezauważalny, przekazuje odniesienie do instancji klasy zewnętrznej Bicycle. Bez instancji klasy zewnętrznej obiekt klasy wewnętrznej po prostu nie mógłby istnieć. W przypadku klas zagnieżdżonych statycznie tak nie jest. Obiekt statycznej klasy zagnieżdżonej jest całkowicie zdolny do samodzielnego istnienia. Pod tym względem klasy statyczne są bardziej „niezależne” niż niestatyczne. Jedyne co musisz wiedzieć to to, że tworząc taki obiekt musisz podać nazwę klasy zewnętrznej:

public class Main {

   public static void main(String[] args) {

       Boeing737.Drawing drawing1 = new Boeing737.Drawing();
       Boeing737.Drawing drawing2 = new Boeing737.Drawing();
   }
}
Dlaczego sprawiliśmy, że Drawingklasa była statyczna, skoro na ostatniej lekcji zrobiliśmy toSeatklasa (reprezentująca siodełko rowerowe) niestatyczna? Tak jak poprzednio, dodajmy trochę "filozofii", aby zrozumieć przykład :) W przeciwieństwie do siodełka rowerowego, koncepcja rysunku technicznego nie jest sztywno związana z koncepcją samolotu. Bez roweru osobny obiekt siedzenia rowerowego byłby najczęściej bez znaczenia (choć nie zawsze, o czym rozmawialiśmy na ostatniej lekcji). Koncepcja rysunku technicznego ma sens sama w sobie. Na przykład może być przydatny dla inżynierów planujących konserwację samolotu. Samolot nie jest potrzebny do sporządzenia planu i może znajdować się w dowolnym miejscu. Potrzebny jest tylko rysunek techniczny. Ponadto wszystkie samoloty tego samego modelu będą miały ten sam rysunek inżynierski, więc nie ma tak ścisłego związku, jak w przypadku siodełka rowerowego. DlategoDrawingobiekt nie potrzebuje odniesienia do konkretnego obiektu samolotu. 2. Różny dostęp do zmiennych i metod klasy zewnętrznej. Statyczna klasa zagnieżdżona może uzyskiwać dostęp tylko do pól statycznych klasy zewnętrznej. W naszym przykładzie Drawingklasa ma getMaxPassengersCount()metodę, która zwraca wartość maxPassengersCountzmiennej statycznej klasy zewnętrznej. Nie możemy jednak utworzyć getManufactureYear()metody w Drawingklasie, która zwracałaby wartość manufactureYear. W końcu manufactureYearzmienna nie jest statyczna, co oznacza, że ​​musi należeć do określonej instancji Boeing737. A jak już odkryliśmy, w przypadku statycznie zagnieżdżonych klas obiekt klasy zewnętrznej może być łatwo nieobecny. Stąd ograniczenie :) Nie ma znaczenia, jaki modyfikator dostępu ma zmienna statyczna w klasie zewnętrznej. Nawet jeśli to jestprivate, statyczna klasa zagnieżdżona nadal będzie miała dostęp. Wszystko to dotyczy nie tylko dostępu do zmiennych statycznych, ale również metod statycznych. WAŻNY! W deklaracji klasy wewnętrznej staticsłowo kluczowe nie oznacza, że ​​można utworzyć tylko jeden obiekt. Nie myl obiektów ze zmiennymi. Jeśli mówimy o zmiennych statycznych, to tak, istnieje pojedyncza instancja zmiennej klasy statycznej, na przykład maxPassangersCount. Ale kiedy staticjest zastosowany do klasy zagnieżdżonej, oznacza to tylko, że jej obiekty nie zawierają odniesień do obiektów klasy zewnętrznej. A samych obiektów możemy stworzyć tyle, ile chcemy:

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);
           }
       }
   }
}
Zadeklarowaliśmy tę main()metodę bezpośrednio w zagnieżdżonej klasie (nie ma ku temu specjalnego powodu — tylko po to, aby poinformować, że jest to możliwe) i stworzyliśmy 5 Drawingobiektów. Pomimo faktu, że nie mamy ani jednego obiektu klasy zewnętrznej. Jak widać, nie przysporzyło to żadnych problemów :) Dane wyjściowe konsoli:

Drawing{id=1} 
Drawing{id=2} 
Drawing{id=3} 
Drawing{id=4} 
Drawing{id=5}
I na tym kończymy naszą lekcję! Na wszelki wypadek zostawiam link do sekcji o nich w dokumentacji Oracle . Jeśli coś nadal pozostaje niejasne, przeczytaj. Teraz nadszedł czas, abym rozwiązał kilka zadań! :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION