„Здрасти, Амиго!“

— Здравей, Ели!

„Днес имаме много интересна тема. Днес ще ви разкажа за вложените класове.“

"Ако даден клас е деклариран в друг клас, тогава той е вложен клас. Нестатичните вложени класове се наричат ​​вътрешни класове."

„Обектите от вътрешен клас са вложени в обекти от външния клас и следователно имат достъп до променливите на външния клас.“

Пример
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);
  }
 }
}

"Имайте предвид, че класът Door има метод getDoorHeight. Той използва променливата за височина на обекта Car и връща височината на вратата."

Вложени класове - 1

„Обект Door не може да съществува независимо от обект Car. В крайна сметка той използва променливите на обект Car. Компилаторът невидимо добавя към конструктора и към класа Door препратка към външния обект Car, така че методите на вътрешния клас Door може да има достъп до променливите на външния клас Car и да извиква неговите методи."

„Вложени обекти. Има смисъл за мен. Съдейки по диаграмата, всичко е доста ясно.“

— И така е. С изключение на няколко нюанса.

„Класът вътрешна врата има препратка към обекта „Кола“, следователно:“

1) Не можете да създадете обект Door вътре в статичен метод на класа Car, тъй като статичните методи не съдържат препратка към обекта Car, който имплицитно се предава на конструктора Door.

Правилно Неправилно
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) Класът Door не може да съдържа статични променливи or методи.

Правилно Неправилно
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;
  }
 }
}

„И Howво, ако имам нужда от променлива, която се споделя от всички обекти на Door?“

"Винаги можете просто да го декларирате в класа Car. Тогава той ще бъде споделен от всички обекти Door, вложени в обект Car."

3) Забележка: ако вътрешният клас е деклариран като публичен, негови екземпляри могат да бъдат създадени извън външния клас, но първо трябва да съществува екземпляр на външния клас:

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

4) И още един коментар, който почти забравих.

„Тъй като имаме два вложени обекта, методите на вътрешния обект имат достъп до две препратки, наречени „това“:“

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

„Нарочно декларирах променливи със същото име в класовете.“

„За достъп до променлива от външния клас, когато е скрита, or за достъп до „this“ във вътрешен клас, просто напишете „YourClassName.this“:“

Как да получите достъп до „това“ на външен (or друг) клас
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

„Така че, ако напишем „това“ вътре в метода на вътрешен клас, тогава „това“ се отнася за вътрешния клас?“

"Да точно."

„Какво мислиш за вътрешните класове, Амиго?“

"Те са много интересни. Не бих казал, че са твърде трудни."

„Има много ограничения, но те изглеждат доста логични, след като обяснихте откъде идват тези ограничения и защо съществуват.

„Освен това, от два месеца пиша вложени класове в задачи, но едва сега осъзнавам Howво всъщност съм писал.“

— Благодаря за чудесния урок, Ели.

— Радвам се, че ти хареса, Амиго.