JavaRush /Blog Java /Random-ES /clases anidadas estáticas

clases anidadas estáticas

Publicado en el grupo Random-ES
¡Hola! Seguimos explorando el tema de las clases anidadas en Java. En la última lección hablamos de clases anidadas no estáticas o, como también se les llama, clases internas. Clases anidadas estáticas - 2Hoy pasemos a otro grupo y echemos un vistazo más de cerca a las clases anidadas estáticas. Clases anidadas estáticas - 3¿En qué se diferencian de otros grupos? Al declarar dicha clase, utilizamos la ya familiar palabra clave estática:
public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

       public static int getMaxPassengersCount() {

           return maxPassengersCount;
       }
   }
}
Clases anidadas estáticas - 4En este ejemplo, tenemos una clase externa Boeing737que crea un avión de este modelo. Y tiene un constructor con un parámetro: el año de fabricación ( int manufactureYear). También hay una variable estática int maxPassengersCount: el número máximo de pasajeros. Será igual para todos los aviones del mismo modelo, por lo que sólo necesitamos una copia. Además, tiene una clase interna estática Drawing: plano de avión. En esta clase podemos resumir toda la información de servicio de la aeronave. En nuestro ejemplo, por simplicidad, lo limitamos al año de fabricación, pero puede contener mucha más información. Clases anidadas estáticas - 5Como comentamos en la última lección, la creación de una clase anidada aumenta la encapsulación y promueve una abstracción más realista. ¿Cuál es la diferencia entre clases anidadas estáticas y no estáticas? 1. Un objeto de clase estática Drawingno almacena una referencia a una instancia específica de la clase externa. Recuerde el ejemplo de la última conferencia con una bicicleta:
public class Bicycle {

   private String model;
   private int mawWeight;

   public Bicycle(String model, int mawWeight) {
       this.model = model;
       this.mawWeight = mawWeight;
   }

   public void start() {
       System.out.println("¡Ir!");
   }

   public class SteeringWheel {

       public void right() {
           System.out.println("¡Volante a la derecha!");
       }

       public void left() {

           System.out.println("¡Volante a la izquierda!");
       }
   }

}
Allí hablamos de cómo SteeringWheeluna referencia a un objeto de la clase externa (bicicleta) se pasa a cada instancia de la clase interna (volante) sin que nos demos cuenta Bicycle. Sin un objeto de la clase externa, un objeto de la clase interna simplemente no podría existir. Esto no es cierto para las clases anidadas estáticas. Un objeto de una clase anidada estática puede existir fácilmente por sí solo. En este sentido, las clases estáticas son más "independientes" que las clases no estáticas. El único punto es que al crear dicho objeto es necesario especificar el nombre de la clase externa:
public class Main {

   public static void main(String[] args) {

       Boeing737.Drawing drawing1 = new Boeing737.Drawing();
       Boeing737.Drawing drawing2 = new Boeing737.Drawing();
   }
}
¿Por qué hicimos la clase Drawingestática, pero en la última conferencia la clase Seat(asiento de bicicleta) no era estática? Como la última vez, agreguemos un poco de "filosofía" para entender el ejemplo :) A diferencia de un asiento de bicicleta, la esencia del dibujo no está tan estrechamente ligada a la esencia del avión. Un objeto de asiento separado, sin una bicicleta, a menudo no tendrá sentido (aunque no siempre; hablamos de esto en la última lección). La esencia del dibujo tiene sentido en sí misma. Por ejemplo, puede resultar útil para los ingenieros que planifican reparaciones de aviones. No necesitan el avión para su planificación y pueden ubicarse en cualquier lugar; basta con un dibujo. Además, para todos los aviones del mismo modelo, el dibujo seguirá siendo el mismo, por lo que no existe una conexión tan rígida como la de un asiento con una bicicleta. Por lo tanto, el objeto Drawingno necesita un vínculo con un objeto de aeronave específico. 2. Acceso diferente a variables y métodos de una clase externa. Una clase anidada estática sólo puede acceder a campos estáticos de la clase externa. En nuestro ejemplo, la clase Drawingtiene un método getMaxPassengersCount()que devuelve el valor de una variable estática maxPassengersCountde una clase externa. Sin embargo, no podemos crear un método getManufactureYear()para Drawingdevolver un valor manufactureYear. Después de todo, una variable manufactureYearno es estática, lo que significa que debe pertenecer a una instancia específica Boeing737. Y como ya hemos descubierto, en el caso de clases anidadas estáticas, es fácil que falte el objeto de la clase externa. De ahí la limitación :) No importa qué modificador de acceso tenga la variable estática en la clase externa. Incluso si lo es private, todavía habrá acceso desde una clase anidada estática. Todo lo anterior se refiere no sólo al acceso a variables estáticas, sino también a métodos estáticos. ¡IMPORTANTE! La palabra staticen una declaración de clase interna no significa que solo se pueda crear un objeto. No confunda objetos con variables. Si hablamos de variables estáticas, sí, una variable de clase estática, por ejemplo, maxPassangersCountexiste en una única copia. Pero cuando se aplica a una clase anidada, staticsólo significa que sus objetos no contienen referencias a objetos de la clase externa. Y podemos crear tantos objetos como queramos:
public class Boeing737 {

   private int manufactureYear;
   private static int maxPassengersCount = 300;

   public Boeing737(int manufactureYear) {
       this.manufactureYear = manufactureYear;
   }

   public int getManufactureYear() {
       return manufactureYear;
   }

   public static class Drawing {

       private int id;

       public Drawing(int id) {
           this.id = id;
       }

       public static int getPassengersCount() {

           return maxPassengersCount;
       }

       @Override
       public String toString() {
           return "Drawing{" +
                   "id=" + id +
                   '}';
       }

       public static void main(String[] args) {

           for (int i = 1; i < 6; i++) {

               Boeing737.Drawing drawing = new Boeing737.Drawing(i);
               System.out.println(drawing);
           }
       }
   }
}
Declaramos el método main()directamente en la clase anidada (no hay ninguna razón particular para esto, solo para que sepas que es posible) y creamos 5 objetos Drawing. A pesar de que no tenemos ni un solo objeto de una clase externa. Como puede ver, no hubo problemas :) Salida de la consola:

Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
¡Esto concluye nuestra lección! Por si acaso te dejo un enlace al apartado sobre ellos en la documentación de Oracle . Léelo si hay algún punto poco claro. ¡Ahora es el momento de resolver un par de problemas! :)
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION