Inner classes en Java

Cuando trabajamos con Java, es común encontrarnos con clases que crecen demasiado, acumulando muchos métodos y atributos, lo que dificulta navegar y mantener el código. Para mejorar esta situación, podemos aprovechar las clases internas, una herramienta que nos permite organizar mejor nuestro código y mantenerlo más modular.

Una clase interna es simplemente una clase definida dentro de otra clase, de forma similar a cómo declaramos métodos o atributos. Podemos asignarle modificadores de visibilidad como private o public, o dejarla con visibilidad por defecto. Por ejemplo, imaginemos que tenemos una clase Triángulo y dentro de ella definimos una clase privada llamada CalculadoraÁrea. Esta clase interna puede contener atributos y métodos propios, y aunque está anidada dentro de Triángulo, mantiene su propia identidad.

public class Triángulo {
    private double base;
    private double altura;

    private class CalculadoraÁrea {
        private double area;

        public CalculadoraÁrea() {
            this.area = (base * altura) / 2;
        }

        @Override
        public String toString() {
            return "Área: " + area;
        }
    }

    public Triángulo(double base, double altura) {
        this.base = base;
        this.altura = altura;
    }

    public void imprimirÁrea() {
        CalculadoraÁrea calculadora = new CalculadoraÁrea();
        System.out.println(calculadora.toString());
    }
}

Lo interesante de las clases internas es que pueden acceder a los atributos y métodos de la clase que las contiene, siempre que pertenezcan a la misma instancia. En el ejemplo, CalculadoraÁrea puede usar directamente base y altura de Triángulo para calcular el área. Sin embargo, desde fuera de Triángulo, no podemos acceder directamente a los atributos de CalculadoraÁrea, ya que son parte de la clase interna.

¿Por qué usar clases internas? Una razón importante es limitar la visibilidad. Al hacer una clase interna privada, garantizamos que solo se use dentro de la clase que la contiene, evitando que otras partes del código accedan o dependan de ella. Esto es útil para encapsular funcionalidades específicas que no tienen sentido fuera de ese contexto.

Además, las clases internas nos permiten agrupar datos relacionados que no encajan bien en un único atributo simple. Por ejemplo, si queremos representar una coordenada que tiene dos valores flotantes, podemos crear una clase interna que agrupe esos valores y la usemos como un solo elemento dentro de la clase principal.

Es importante tener en cuenta que, aunque las clases internas facilitan el acceso a los datos de la clase externa, debemos usarlas con moderación. Si la clase interna depende demasiado de los atributos externos, se vuelve muy acoplada y difícil de reutilizar o modificar por separado. Por eso, conviene reservarlas para casos donde la información o funcionalidad que encapsulan tiene sentido únicamente en el contexto de la clase que las contiene.

Un uso frecuente de las clases internas es en la implementación de Listeners, Runnable para hilos o adaptadores de eventos. En lugar de crear clases anónimas o archivos separados, podemos definir estas clases dentro de la clase principal para mantener el código más organizado y legible.

Para profundizar en este tema, podemos buscar información sobre Inner Class en la documentación de Java, donde encontraremos más detalles y ejemplos. También existen las clases estáticas anidadas, que tienen un comportamiento diferente y merecen una explicación aparte.

En definitiva, las clases internas son una herramienta valiosa para mantener nuestro código Java más limpio, modular y con una visibilidad controlada, siempre que las usemos para lo que realmente están pensadas y evitemos abusar de su capacidad de acceder a los datos externos.

Lista de reproducción
  1. 1
    ¿Cómo funciona Comparator en Java?
    10 minutos
  2. 2
    ¿Para qué sirve Override?
    4 minutos
  3. 3
    Cómo usar la clase Properties en Java
    14 minutos
  4. 4
    Interfaces funcionales y funciones flecha
    8 minutos
  5. 5
    Bloque static de Java: inicializadores estáticos y otros usos
    7 minutos
  6. 6
    import static, ¿para qué sirve?
    3 minutos
  7. 7
    Uso de Optional en Java
    10 minutos
  8. 8
    Introducción al Scanner de Java
    11 minutos
  9. 9
    ¿Para qué sirve el modificador static de Java?
    6 minutos
  10. 10
    Funciones variádicas en Java
    6 minutos
  11. 11
    Inner classes en Java
    8 minutos
  12. 12
    var en Java: una introducción para gente nueva
    7 minutos
  13. 13
    Switch expressions en Java
    10 minutos
  14. 14
    Java: del instanceof al Pattern Matching
    7 minutos
  15. 15
    Sealed classes en Java
    8 minutos
  16. 16
    Getters y setters o atributos públicos en Java, ¿qué es mejor?
    9 minutos
  17. 17
    El String[] args del método main de Java
    8 minutos
  18. 18
    Introducción a clases anónimas en Java
    6 minutos
  19. 19
    Introducción a enum en Java
    6 minutos