1. Clases internas

Recientemente aprendiste que existen variables estáticas y métodos estáticos. Resulta que también hay clases estáticas. Pero abordaremos este tema desde la distancia.

En Java, puede declarar clases dentro de clases. E incluso clases dentro de clases que están dentro de clases dentro de clases. Todo parece muy simple:

class OuterClass
{
   variables of the class
   methods of the class

   class NestedClass
   {
      variables of the class
      methods of the class
   }
}

Simplemente declaramos una clase dentro de otra. Tan sencillo como eso.

Ejemplo:

public class Solution
{
   static ArrayList<Point> points = new ArrayList<Point>();

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}

Las clases anidadas pueden ser estáticas o no estáticas. Las clases anidadas estáticas se denominan simplemente clases anidadas estáticas . Las clases anidadas no estáticas se denominan clases internas ( innerclasses ).



2. Clases estáticas

Las clases anidadas estáticas se pueden usar fuera de su clase externa. Si dicha clase tiene el modificador de acceso público, entonces se puede usar en cualquier parte del programa. Tales clases son casi indistinguibles de cualquier clase ordinaria. Pero hay un par de diferencias.

Nombre de la clase

Si desea hacer referencia a una clase anidada estática desde un lugar que no sea su clase externa, debe especificar el nombre de la clase, que consiste en el nombre de la clase externa y el nombre de la clase anidada. Aquí está la apariencia general de este nombre:

OuterClass.InnerClass

Ejemplos:

clase exterior clase anidada Nombre completo de la clase anidada
com.codegym.Solution
Point
com.codegym.Solution.Point
java.util.Map
Entry
java.util.Map.Entry
java.util.Files
DirectoryStream
java.util.Files.DirectoryStream
java.nio.WindowsPath
Closeable
java.nio.WindowsPath.Closeable

Si una clase anidada tiene su propia clase anidada, sus nombres simplemente se unen mediante un punto.

Un ejemplo típico de una clase anidada en el JDK es la Entryclase dentro de la Mapclase. Si desea obtener el conjunto de pares clave-valor almacenados en un HashMapobjeto, utilice el entrySet()método, que devuelve un .Set<Map.Entry>

Tenga en cuenta que es un ejemplo de una clase externa y una clase anidada.Map.Entry

Creando un objeto

Es muy fácil crear un objeto de una clase anidada estática. Así es como se ve:

OuterClass.NestedClass name = new OuterClass.NestedClass();

Es lo mismo que con las clases ordinarias, pero el nombre consta de dos partes.

Llamar a métodos estáticos

Si una clase estática tiene métodos estáticos, puede acceder a ellos de la misma forma que los métodos estáticos de las clases ordinarias (pero el nombre de la clase constará de dos partes).

OuterClass.NestedClass.staticMethod();

Acceso a variables estáticas

Acceder a las variables estáticas públicas de una clase anidada también es fácil:

OuterParent.NestedClass.nameOfStaticVariable


3. Características de las clases estáticas

Las clases anidadas estáticas tienen la menor razón para llamarse estáticas. Se comportan como clases regulares . No hay restricciones para acceder a ellos desde métodos no estáticos.

Si está trabajando con una clase anidada estática dentro de su clase externa, no notará ninguna diferencia con respecto a la clase más ordinaria (no anidada ni estática).

Ejemplo:

Clase de punto anidada estática Clase de Punto Ordinario.
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }
}

class Point
{
   int x;
   int y;
}

Si toma una clase anidada estática y la saca de su clase externa, lo único que cambiará es que la nueva clase ya no podrá acceder a las private staticvariables y métodos de su clase externa anterior.

Ejemplo:

Clase de punto anidada estática Clase de Punto Ordinario.
public class Solution
{
   private static ArrayList<Point> points;

   static class Point
   {
      int x;
      int y;

      public static void main(String[] args)
      {
         Point point = new Point();
         point.x = 100;
         point.y = 200;

         // This will work
         points = new ArrayList<Point>();
         points.add(point);
      }
   }
}
public class Solution
{
   private static ArrayList<Point> points;
}

class Point
{
   int x;
   int y;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;

      // This will generate an error
      points = new ArrayList<Point>();
      points.add(point);
   }
}

¡ El método en la clase mainordinaria no puede acceder a la variable de la clase!Pointprivate static pointsSolution

Esta es la principal diferencia entre una clase anidada estática y una clase ordinaria. Los métodos de una clase anidada estática pueden acceder a todas las variables y métodos estáticos de su clase externa, incluso si están declarados private.

Y si lo piensas, ¿por qué debería sorprenderte? El privatemodificador dice explícitamente que solo se puede acceder a las variables y métodos marcados por este modificador desde dentro de su clase. ¿Hay una clase anidada estática dentro de su clase externa? ¡Sí, así que no hay problema! Accede a ellos tanto como quieras.