Translate

martes, 19 de agosto de 2025

Inner Classes en Java vs Nested Classes en C#


En muchos lenguajes podemos anidar clases dentro de otras, pero no siempre significan lo mismo ni tienen las mismas capacidades. Veamos la comparación entre Java y C#.

Java tiene Inner Classes. Cuando declaramos una clase dentro de otra, tenemos dos opciones principales:

Static nested class: funciona como una clase estática, no tiene referencia a la instancia externa.

Inner class (no estática): mantiene una referencia implícita a la instancia de la clase que la contiene.

Esto permite escribir cosas como:


class Contenedora {

    private int valor = 42;


    class Inner {

        void mostrar() {

            // Acceso implícito a la instancia externa

            System.out.println("Valor: " + Contenedora.this.valor);

        }

    }


    public static void main(String[] args) {

        Contenedora c = new Contenedora();

        Contenedora.Inner i = c.new Inner();

        i.mostrar(); // Valor: 42

    }

}


Aquí, Contenedora.this es una referencia implícita que permite acceder directamente a la instancia de la clase externa.


En C# tenemos Nested Classes. En C#, todas las clases anidadas son conceptualmente clases estáticas (aunque no las declares static).

Esto significa que no existe referencia implícita a la instancia externa.


Ejemplo equivalente en C#:


public class Contenedora

{

    private int valor = 42;


    public class Nested

    {

        // No existe "Contenedora.this"

        public void Mostrar(Contenedora externa)

        {

            Console.WriteLine($"Valor: {externa.valor}");

        }

    }


    public static void Main()

    {

        var c = new Contenedora();

        var n = new Nested();

        n.Mostrar(c); // Valor: 42

    }

}


Si querés acceder a los atributos de la clase externa, tenés que pasar explícitamente la referencia (Contenedora externa en este caso).

Entonces, Java Inner Class:

  • Tiene un puntero implícito a la instancia externa.
  • Podés usar Outer.this.atributo.
  • Muy útil en callbacks o cuando la clase interna depende fuertemente de la externa.


C# Nested Class:

  • No tiene referencia implícita.
  • No existe Outer.this.
  • Son más “independientes”, como una clase estática que solo vive en el scope de otra.


¿Por qué esta diferencia?

  • Java diseñó las inner classes como un mecanismo para trabajar con GUI y callbacks (ejemplo clásico: listeners en Swing). Por eso necesitan la referencia a la instancia externa.
  • C# tomó otro camino: sus delegates y lambdas con closures resuelven ese escenario sin necesidad de que las nested classes tengan referencia implícita.