Sobes.tech
Middle

Habla sobre las clases anidadas y en qué casos se aplican.

sobes.tech AI

Respuesta de la IA

Las clases anidadas (Nested Classes) en Java son clases definidas dentro de otra clase. Se dividen en dos tipos: estáticas (Static Nested Classes) y internas (Inner Classes).

Clases anidadas estáticas

  • Se declaran con el modificador static.
  • Solo tienen acceso a los miembros estáticos de la clase externa (incluso los ocultos).
  • No tienen acceso a los miembros no estáticos de la clase externa.
  • Para crear una instancia de una clase anidada estática no se requiere una instancia de la clase externa:
    // Clase externa
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Clase anidada estática
        static class StaticNested {
            void accessOuter() {
                // Acceso al campo estático de la clase externa
                System.out.println(Outer.outerStaticField);
                // No hay acceso a outerInstanceField
                // System.out.println(outerInstanceField); // Error de compilación
            }
        }
    }
    
    // Uso de la clase anidada estática
    class Main {
        public static void main(String[] args) {
            Outer.StaticNested nestedObject = new Outer.StaticNested();
            nestedObject.accessOuter();
        }
    }
    

Clases internas

  • No se declaran con el modificador static.
  • Tienen acceso completo a todos los miembros de la clase externa (estáticos y no estáticos, incluso los ocultos).
  • Una instancia de la clase interna no puede existir sin una instancia de la clase externa.
  • Para crear una instancia de la clase interna se requiere una instancia de la clase externa:
    // Clase externa
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Clase interna
        class Inner {
            void accessOuter() {
                // Acceso al campo estático de la clase externa
                System.out.println(Outer.outerStaticField);
                // Acceso al campo no estático de la clase externa
                System.out.println(outerInstanceField);
            }
        }
    }
    
    // Uso de la clase interna
    class Main {
        public static void main(String[] args) {
            Outer outerObject = new Outer();
            Outer.Inner innerObject = outerObject.new Inner();
            innerObject.accessOuter();
        }
    }
    

Las clases internas se subdividen en:

  • Clases internas regulares: Se definen directamente dentro del cuerpo de la clase externa.
  • Clases internas locales: Se definen dentro de métodos, constructores o bloques de inicialización. Son visibles solo dentro de ese bloque.
    class Outer {
        void display() {
            class LocalInner { // Clase interna local
                void message() {
                    System.out.println("Clase interna local");
                }
            }
            LocalInner obj = new LocalInner();
            obj.message();
        }
    }
    
  • Clases internas anónimas: Clases sin nombre, utilizadas para crear una instancia de una clase o interfaz y proporcionar su implementación de inmediato. Se usan frecuentemente con escuchas de eventos.
    interface Greeting {
        void sayHello();
    }
    
    class Main {
        public static void main(String[] args) {
            Greeting greeting = new Greeting() { // Clase interna anónima
                @Override
                public void sayHello() {
                    System.out.println("¡Hola!");
                }
            };
            greeting.sayHello();
        }
    }
    

¿Cuándo se aplican las clases anidadas?:

  • Agrupamiento lógico: Si una clase es solo parte de otra clase y tiene sentido agruparlas juntas. Esto mejora la legibilidad y mantenibilidad del código.
  • Encapsulación: Las clases anidadas pueden acceder a los miembros de la clase externa, lo que proporciona una relación más estrecha y la capacidad de ocultar detalles de implementación.
  • Código más legible: Cuando una clase pequeña y sencilla solo se usa en un lugar, anidarla puede hacer que el código sea más ordenado.
  • Uso eficiente de recursos: Las clases internas tienen acceso a los miembros de la clase externa sin necesidad de pasarlos explícitamente, lo que puede simplificar el código. Un ejemplo son las implementaciones de iteradores.
  • Implementación de interfaces o extensión de clases en contexto: Las clases internas anónimas se usan a menudo para proporcionar implementaciones compactas de interfaces o clases abstractas "en tiempo real".
  • Ocultamiento de la implementación: Ocultar una clase dentro de otra, haciéndola invisible desde fuera.

Comparación entre clases anidadas estáticas y internas:

Parámetro Clase anidada estática Clase interna
Modificador static No
Acceso a los miembros de la clase externa Solo estáticos (incluso privados) Todos los miembros (estáticos y no estáticos, privados)
Se requiere una instancia de la clase externa para crear No
Relación con la instancia de la clase externa No

La elección entre una clase anidada estática y una interna depende de si la clase anidada necesita acceso a los miembros no estáticos de la clase externa. Si lo necesita, use la clase interna. Si no, la clase anidada estática es una opción más adecuada, ya que no está vinculada a una instancia de la clase externa y puede ser más eficiente.