Las clases internas no son fáciles de entender, pero en pocas palabras, son una clase que contiene otra clase dentro.

Así como una persona está compuesta por estructuras corporales como el cerebro, las extremidades y los órganos, la clase interna equivale a uno de esos órganos, por ejemplo, el corazón: también tiene sus propios atributos y comportamientos (sangre, latidos).

Obviamente, aquí no se puede representar un corazón solo con un atributo o un método, sino que se necesita una clase.

Y el corazón está dentro del cuerpo humano, igual que la clase interna está dentro de la clase externa.

Ejemplo 1: Estructura básica de la clase interna

//外部类
class Out {
    private int age = 12;
     
    //内部类
    class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
        //或者采用下种方式访问
        /*
        Out out = new Out();
        Out.In in = out.new In();
        in.print();
        */
    }
}

Resultado de ejecución: 12

Del ejemplo anterior no es difícil ver que las clases internas realmente dañan gravemente una buena estructura de código, pero ¿por qué usar clases internas entonces?

Porque la clase interna puede usar libremente las variables miembro de la clase externa (incluidas las privadas) sin necesidad de crear un objeto de la clase externa, y esta es la única ventaja de las clases internas.

Así como el corazón puede acceder directamente a la sangre del cuerpo, en lugar de que un médico extraiga sangre.

Después de compilar el programa, se generan dos archivos .class: Out.class y Out$In.class.

El símbolo $ representa el punto en Out.In del programa anterior.

Out.In in = new Out().new In()Se puede usar para crear objetos de la clase interna. Este método tiene dos pequeños puntos de conocimiento a tener en cuenta:

  • 1. El Out inicial es para indicar en qué clase externa se encuentra el objeto de la clase interna que se va a crear.
  • 2. Primero debe existir un objeto de la clase externa para poder crear un objeto de la clase interna, porque el propósito de la clase interna es acceder a las variables miembro de la clase externa.
class Out {
    private int age = 12;
     
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部变量:" + age);
            System.out.println("内部类变量:" + this.age);
            System.out.println("外部类变量:" + Out.this.age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}

Resultado de ejecución:

局部变量:14
内部类变量:13
外部类变量:12

Del Ejemplo 1 se puede ver que, cuando no hay variables miembro ni variables locales con el mismo nombre, la clase interna accede directamente a las variables miembro de la clase externa, sin necesidad de especificarOut.this.nombreDePropiedad。

De lo contrario, las variables locales de la clase interna sobrescribirán las variables miembro de la clase externa.

Y para acceder a las variables miembro de la propia clase interna se puede usarthis.nombreDePropiedady para acceder a las variables miembro de la clase externa se necesita usarOut.this.nombreDePropiedad。

Ejemplo 3: Clase interna estática

class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}

Resultado de ejecución: 12

Se puede ver que si se usa static para hacer estática la clase interna, entonces la clase interna solo puede acceder a las variables miembro estáticas de la clase externa, lo que tiene limitaciones.

En segundo lugar, como la clase interna se ha hecho estática, Out.In se puede considerar como un todo, y se puede crear directamente un objeto de la clase interna con new (se accede a static mediante el nombre de la clase; no importa si se genera o no un objeto de la clase externa).

Ejemplo 4: Clase interna privada/h3>
class Out {
    private int age = 12;
     
    private class In {
        public void print() {
            System.out.println(age);
        }
    }
    public void outPrint() {
        new In().print();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        //此方法无效
        /*
        Out.In in = new Out().new In();
        in.print();
        */
        Out out = new Out();
        out.outPrint();
    }
}

Resultado de ejecución: 12

Si se desea que una clase interna sea operada únicamente por métodos de la clase externa, entonces se puede declarar la clase interna como private.

En el código anterior, debemos crear un objeto de la clase In dentro de la clase Out para operarlo, y ya no podemos usarOut.In in = new Out().new In()para crear un objeto de la clase interna.

Es decir, en este momento, la clase interna solo puede ser controlada por la clase externa.

Es como decir que mi corazón solo puede ser controlado por mi cuerpo; otras personas no pueden acceder directamente a él.

Ejemplo 5: Clase interna en un método

class Out {
    private int age = 12;
 
    public void Print(final int x) {
        class In {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }
        new In().inPrint();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out out = new Out();
        out.Print(3);
    }
}

Resultado de ejecución:

3
12

En el código anterior, movimos la clase interna al método de la clase externa, y luego, dentro del método de la clase externa, creamos un objeto de la clase interna para llamar al método de la clase interna.

Si en este momento necesitamos pasar parámetros al método de la clase externa, los parámetros formales del método de la clase externa deben definirse con final.

En cuanto a final, aquí no tiene un significado especial, es solo una forma de representación.