"¡Hola, amigo!"

"¡Hola, Ellie!"

"Hoy tenemos un tema muy interesante. Hoy les voy a hablar de las clases anidadas".

"Si una clase se declara dentro de otra clase, entonces es una clase anidada. Las clases anidadas no estáticas se denominan clases internas".

"Los objetos de una clase interna están anidados dentro de los objetos de la clase externa y, por lo tanto, pueden acceder a las variables de la clase externa".

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

"Tenga en cuenta que la clase Door tiene un método getDoorHeight. Utiliza la variable de altura del objeto Car y devuelve la altura de la puerta".

Clases anidadas - 1

"Un objeto Puerta no puede existir independientemente de un objeto Coche. Después de todo, utiliza las variables del objeto Coche. El compilador añade de forma invisible al constructor y a la clase Puerta una referencia al objeto Coche exterior, de modo que los métodos de la clase Puerta interior puede acceder a las variables de la clase Car externa y llamar a sus métodos".

"Objetos anidados. Tiene sentido para mí. A juzgar por el diagrama, todo es bastante sencillo".

"Y así es. Excepto por un par de matices".

"La clase Puerta interior tiene una referencia al objeto Coche, por lo tanto:"

1) No puede crear un objeto Puerta dentro de un método estático de la clase Coche, porque los métodos estáticos no contienen una referencia al objeto Coche que se pasa implícitamente al constructor Puerta.

Correcto Incorrecto
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) La clase Puerta no puede contener variables o métodos estáticos.

Correcto Incorrecto
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;
  }
 }
}

"¿Y si necesito una variable compartida por todos los objetos Door?"

"Siempre puede simplemente declararlo en la clase Coche. Luego será compartido por todos los objetos Puerta anidados en un objeto Coche".

3) Nota: si la clase interna se declara como pública, se pueden crear instancias fuera de la clase externa, pero primero debe existir una instancia de la clase externa:

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

4) Y un comentario más que casi se me olvida.

"Dado que tenemos dos objetos anidados, los métodos del objeto interno tienen acceso a dos referencias llamadas 'esto':"

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

"Declaré deliberadamente variables con el mismo nombre en las clases".

"Para acceder a una variable de la clase externa cuando está oculta, o para acceder a 'esto' dentro de una clase interna, simplemente escribe 'TuNombreDeClase.esto':"

Cómo acceder al 'esto' de una clase externa (o cualquier otra)
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

"Entonces, si escribimos 'esto' dentro del método de una clase interna, ¿entonces 'esto' se refiere a la clase interna?"

"Sí exactamente."

"¿Qué piensas de las clases internas, Amigo?"

"Son muy interesantes. No diría que son demasiado difíciles".

"Hay muchas restricciones, pero parecen bastante lógicas después de que explicaste de dónde provienen esas restricciones y por qué existen".

"Además, he estado escribiendo clases anidadas en tareas durante dos meses, pero solo ahora me doy cuenta de lo que realmente he estado escribiendo".

"Gracias por la gran lección, Ellie".

"Me alegro de que te haya gustado, amigo".