— Отже, тема номер два – вкладені класи.

Перед оголошенням внутрішнього класу ми можемо поставити ключове слово static, і тоді внутрішній клас стане вкладеним.

Давай розберемося, що означає слово static поряд з оголошенням вкладеного класу. Як ти думаєш?

— Якщо змінна оголошена статичною, вона існує в єдиному екземплярі, а якщо вкладений клас – статичний, то можна створити лише один об'єкт такого класу?

— Нехай слово static у цьому випадку не вводить тебе у оману. Якщо змінна оголошена статичною, то вона існує у єдиному екземплярі – це вірно. Але статичний вкладений клас більше схожий на статичний метод у цьому сенсі. Слово static перед оголошенням класу вказує, що цей клас не зберігає у собі посилань на об'єкти зовнішнього класу, всередині якого він оголошений.

— Добре. Звичайні методи потай зберігають посилання на об'єкт, а статичні – ні. Те ж саме і з статичними класами, чи не так?

— Абсолютно. Твоя здогадливість дуже похвальна. Вкладені статичні класи не мають прихованих посилань на об'єкти зовнішнього класу, у якому оголошені.

class Zoo
{
 private static int count = 7;
 private int mouseCount = 1;

 public static int getAnimalCount()
 {
  return count;
 }

 public int getMouseCount()
 {
  return mouseCount;
 }

 public static class Mouse
 {
  public Mouse()
  {
  }
   public int getTotalCount()
  {
   return count + mouseCount; //помилка компіляції
  }
 }
}

Давай поглянемо уважно на цей приклад.

До яких змінних може звертатися статичний метод getAnimalCount?

— Лише до статичних. Це ж статичний метод.

До яких змінних може звертатися метод getMouseCount?

— І до статичних, і до нестатичних. Він потай зберігає посилання (this) на об'єкт типу Zoo.

— Правильно. Статичний вкладений клас Mouse, як і статичний метод, може звертатися до статичних змінних класу Zoo, але не може звертатися до нестатичних.

Ми можемо спокійно створювати об'єкти класу Mouse, навіть коли немає жодного створеного об'єкта класу Zoo. Ось як це можна зробити:

class Home
{
 public static void main(String[] args)
 {
  Zoo.Mouse mouse = new Zoo.Mouse();
 }
}

Фактично клас Mouse – це звичайнісінький клас. Через те, що його оголошено всередині класу Zoo, він має дві особливості.

1) При створенні об'єктів вкладеного класу (як клас Mouse) поза зовнішнім батьківським класом треба ще вказувати через крапку й ім'я зовнішнього класу.

Наприклад так: Zoo.Mouse.

2) Клас Zoo.Mouse і його об'єкти мають доступ до private static змінних і методів класу Zoo (адже клас Mouse теж оголошений всередині класу Zoo).

На цьому сьогодні все.

— Тобто просто додаткове ім'я та все?

Так.

— Це ще простіше, ніж здавалося на перший погляд.