"Bună, Amigo!"

— Bună, Ellie!

"Astăzi avem un subiect foarte interesant. Azi am să vă povestesc despre clasele imbricate."

"Dacă o clasă este declarată în interiorul unei alte clase, atunci este o clasă imbricată. Clasele imbricate non-statice sunt numite clase interioare."

„Obiectele unei clase interioare sunt imbricate în interiorul obiectelor clasei exterioare și, prin urmare, pot accesa variabilele clasei exterioare.”

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

"Rețineți că clasa Door are o metodă getDoorHeight. Folosește variabila înălțime a obiectului Car și returnează înălțimea ușii."

Clase imbricate - 1

„Un obiect Door nu poate exista independent de un obiect Car. La urma urmei, folosește variabilele obiectului Car. Compilatorul adaugă în mod invizibil constructorului și clasei Door o referință la obiectul exterior Car, astfel încât metodele clasei interioare Door poate accesa variabilele clasei exterioare Car și apela metodele acesteia.”

"Obiecte imbricate. Are sens pentru mine. Judecând după diagramă, totul este destul de simplu."

— Și așa este. În afară de câteva nuanțe.

„Clasa interior Door are o referință la obiectul Car, prin urmare:”

1) Nu puteți crea un obiect Door în interiorul unei metode statice a clasei Car, deoarece metodele statice nu conțin o referință la obiectul Car care este implicit transmisă constructorului Door.

Corect Incorect
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) Clasa Door nu poate conține variabile sau metode statice.

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

„Și ce se întâmplă dacă am nevoie de o variabilă care este partajată de toate obiectele Door?”

„Puteți oricând să îl declarați pur și simplu în clasa Car. Apoi va fi partajat de toate obiectele Door imbricate într-un obiect Car.”

3) Notă: dacă clasa interioară este declarată publică, instanțe ale acesteia pot fi create în afara clasei exterioare, dar trebuie să existe mai întâi o instanță a clasei exterioare:

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

4) Și încă un comentariu pe care aproape l-am uitat.

„Deoarece avem două obiecte imbricate, metodele obiectului interior au acces la două referințe numite „acest”:”

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

„Am declarat în mod deliberat variabile cu același nume în clase”.

„Pentru a accesa o variabilă din clasa exterioară atunci când este ascunsă sau pentru a accesa „aceasta” în interiorul unei clase interioare, pur și simplu scrieți „NumeleClasei.this”:”

Cum să accesezi „aceasta” a unei clase exterioare (sau a oricărei alte clase).
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

„Deci, dacă scriem „aceasta” în cadrul unei metode a unei clase interioare, atunci „acest lucru” se referă la clasa interioară?”

— Da. Exact.

— Ce părere ai despre clasele interioare, Amigo?

"Sunt foarte interesante. Nu aș spune că sunt prea dificile."

„Există o mulțime de restricții, dar par destul de logice după ce ai explicat de unde provin acele restricții și de ce există”.

„În plus, am scris clase imbricate în sarcini de două luni, dar abia acum îmi dau seama ce am scris cu adevărat”.

— Mulțumesc pentru marea lecție, Ellie.

— Mă bucur că ți-a plăcut, Amigo.