Klasy zagnieżdżone - 1

Witaj Amigo!

- Cześć, Ellie!

„Dzisiaj będzie bardzo ciekawy temat. Dzisiaj opowiem o klasach wewnętrznych.

Jeśli jedna klasa jest zadeklarowana wewnątrz innej, wówczas taka klasa jest nazywana wewnętrzną.

W tym przypadku obiekty klas wewnętrznych są zagnieżdżone w obiektach klas zewnętrznych i mają dostęp do zmiennych klas zewnętrznych.

Przykład
public class Car
{
 int height = 160;
 ArrayList doors = new ArrayList();

 public Car
 {
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
 }

class Door()
 {
  public int getDoorHeight()
  {
   return (int)(height * 0.80);
  }
 }
}

Zauważ, że klasa Door posiada metodę zwracającą wysokość drzwi - getDoorHeight , metoda ta wykorzystuje zmienną wysokości obiektu Car.

Klasy zagnieżdżone - 2

Obiekt typu Drzwi nie może istnieć oddzielnie od obiektu typu Samochód, ponieważ używa jego zmiennych. Kompilator po cichu dodaje odwołanie do obiektu zewnętrznej klasy Car do konstruktora i klasy Door, dzięki czemu metody wewnętrznej klasy Door mogą uzyskiwać dostęp do zmiennych i wywoływać metody zewnętrznej klasy Car.

- Obiekty zagnieżdżone. Wszystko rozumiem. Sądząc po zdjęciu, tutaj wszystko jest elementarne.

- To prawda. Tylko kilka niuansów.

Wewnętrzna klasa Door ma odniesienie do obiektu klasy Car, więc:

1) Nie można utworzyć obiektu Door wewnątrz metody statycznej w klasie Car: nigdzie nie można uzyskać referencji do obiektu typu Car, który jest niejawnie przekazywany do konstruktora typu Door.

Prawidłowy Zło
public class Car
{
 public static Door createDoor()
 {
  Car car = new Car();
  return car.new Door();
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{
 public static Door createDoor()
 {
  return new Door();
 }

 public class Door
 {
  int width, height;
 }
}

2) Klasa Door nie może zawierać zmiennych i metod statycznych.

Prawidłowy Zło
public class Car
{
 public int count;
 public int getCount()
 {
  return count;
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{

 public class Door
 {
  public static int count;
  int width, height;

  public static int getCount()
  {
   return count;
  }
 }
}

— Co jeśli potrzebuję wspólnej zmiennej dla wszystkich obiektów Drzwi?

Zawsze możesz to po prostu zadeklarować w klasie Car — będzie to wspólna zmienna dla wszystkich obiektów Door zagnieżdżonych w obiekcie Car.

3) Zwróć uwagę, że jeśli klasa wewnętrzna jest zadeklarowana jako publiczna, to jej obiekty mogą być tworzone poza klasą zewnętrzną, ale obiekt klasy zewnętrznej musi być obecny:

Car car = new Car();
Car.Door door = car.new Door();
Car.Door door = new Car().new Door();

4) I jeszcze jedna uwaga - prawie zapomniałem.

Ponieważ mamy dwa zagnieżdżone obiekty, to w metodach obiektu wewnętrznego dostępne są dwa odwołania do tego:

public class Car
{
 int width, height;

 public class Door
 {
  int width, height;

  public void setHeight(int height)
  {
   this.height = height;
  }

  public int getHeight()
  {
   if (height!=0)
    return this.height;
   else
    return (int)(Car.this.height * 0.8);
  }
 }
}

Specjalnie zadeklarowałem te same zmienne w klasach.

Aby odwołać się do zmiennej klasy zewnętrznej, gdy jest ukryta, lub do zmiennej klasy zewnętrznej, po prostu napisz „nazwę klasy” w kropce:

Jak uzyskać dostęp do this klasy zewnętrznej (lub dowolnej).
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

- Tj. jeśli zapiszemy to w metodzie klasy wewnętrznej, to czy this odnosi się do klasy wewnętrznej?

- Tak. Dokładnie.

Jak ci się podobają wewnętrzne zajęcia, Amigo?

- Bardzo interesujące. Nie powiedziałbym, że to bardzo trudne.

Istnieje wiele ograniczeń, ale są one dość logiczne, kiedy wyjaśniłeś mi, skąd i dlaczego się biorą.

I od dwóch miesięcy nieustannie piszę zajęcia zagnieżdżone w zadaniach praktycznych i dopiero teraz zdałem sobie sprawę, co właściwie napisałem.

Dzięki za świetny tutorial Ellie.

„Cieszę się, że ci się podobało, Amigo.