"Olá, amigo!"

"Oi, Ellie!"

"Hoje temos um tópico muito interessante. Hoje vou falar sobre classes aninhadas."

"Se uma classe é declarada dentro de outra classe, então é uma classe aninhada. Classes aninhadas não estáticas são chamadas de classes internas."

"Objetos de uma classe interna são aninhados dentro de objetos da classe externa e podem, portanto, acessar as variáveis ​​da classe externa."

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

"Observe que a classe Door tem um método getDoorHeight. Ele usa a variável height do objeto Car e retorna a altura da porta."

Classes aninhadas - 1

"Um objeto Door não pode existir independentemente de um objeto Car. Afinal, ele usa as variáveis ​​do objeto Car. O compilador adiciona invisivelmente ao construtor e à classe Door uma referência ao objeto Car externo, de modo que os métodos da classe Door interna pode acessar as variáveis ​​da classe Car externa e chamar seus métodos."

"Objetos aninhados. Faz sentido para mim. A julgar pelo diagrama, é tudo bem direto."

"E assim é. Exceto por algumas nuances."

"A classe Porta interna tem uma referência ao objeto Carro, portanto:"

1) Você não pode criar um objeto Door dentro de um método estático da classe Car, porque os métodos estáticos não contêm uma referência ao objeto Car que é passado implicitamente para o construtor Door.

Correto Incorreta
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) A classe Door não pode conter variáveis ​​ou métodos estáticos.

Correto Incorreta
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;
  }
 }
}

"E se eu precisar de uma variável que seja compartilhada por todos os objetos Door?"

"Você sempre pode simplesmente declará-lo na classe Car. Em seguida, ele será compartilhado por todos os objetos Door aninhados em um objeto Car."

3) Nota: se a classe interna for declarada como pública, instâncias dela podem ser criadas fora da classe externa, mas uma instância da classe externa deve existir primeiro:

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

4) E mais um comentário que quase esqueci.

"Como temos dois objetos aninhados, os métodos do objeto interno têm acesso a duas referências chamadas 'this':"

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

"Eu declarei deliberadamente variáveis ​​com o mesmo nome nas classes."

"Para acessar uma variável da classe externa quando ela está oculta, ou para acessar 'this' dentro de uma classe interna, simplesmente escreva 'YourClassName.this':"

Como acessar o 'this' de uma classe externa (ou qualquer outra)
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

"Então, se escrevermos 'this' dentro do método de uma classe interna, então 'this' se refere à classe interna?"

"Sim, exatamente."

"O que você acha das aulas internas, Amigo?"

"Eles são muito interessantes. Eu não diria que são muito difíceis."

"Existem muitas restrições, mas elas parecem bastante lógicas depois que você explica de onde vêm essas restrições e por que elas existem."

"Além disso, tenho escrito classes aninhadas em tarefas por dois meses, mas só agora percebo o que realmente tenho escrito."

"Obrigado pela grande lição, Ellie."

"Estou feliz que você gostou, amigo."