¿Qué es una clase interna de JAVA?

Clasificación interna

En términos generales, las clases internas generalmente incluyen cuatro tipos: clases internas de miembros, clases internas locales, clases internas anónimas y clases internas estáticas.

Clase interna de miembro

class Circle {
    
    
    double radius = 0;
     
    public Circle(double radius) {
    
    
        this.radius = radius;
    }
     
    class Draw {
    
         //内部类
        public void drawSahpe() {
    
    
            System.out.println("drawshape");
        }
    }
}

La clase interna de miembros puede localizar incondicionalmente todos los atributos y métodos de miembros de la clase externa, incluidos los privatemiembros y los miembros estáticos.

class Circle {
    
    
    private double radius = 0;
    public static int count =1;
    public Circle(double radius) {
    
    
        this.radius = radius;
    }
     
    class Draw {
    
         //内部类
        public void drawSahpe() {
    
    
            System.out.println(radius);  //外部类的private成员
            System.out.println(count);   //外部类的静态成员
        }
    }
}

Cabe señalar que cuando la variable miembro o método de la clase interna y la clase externa tienen el mismo nombre, se produce el fenómeno oculto, es decir, se accede por defecto a los miembros de la clase interna del miembro. Si necesita acceder a un miembro con el mismo nombre de una clase externa, debe acceder a él en el siguiente formulario:

// 外部类.this.成员变量
// 外部类.this.成员方法

Si la clase externa quiere acceder a los miembros de la clase interna miembro, primero debe crear un objeto de la clase interna y acceder a él a través de una referencia a este objeto.

El miembro de la clase interna depende de la clase externa, es decir, la premisa de crear un objeto de la clase interna es la existencia de un objeto de la clase externa.

public class Test {
    
    
    public static void main(String[] args)  {
    
    
        //第一种方式:
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  //必须通过Outter对象来创建
         
        //第二种方式:
        Outter.Inner inner1 = outter.getInnerInstance();
    }
}
 
class Outter {
    
    
    private Inner inner = null;
    public Outter() {
    
    
         
    }
     
    public Inner getInnerInstance() {
    
    
        if(inner == null)
            inner = new Inner();
        return inner;
    }
      
    class Inner {
    
    
        public Inner() {
    
    
             
        }
    }
}

Si el miembro de la clase interna Inner está decorado con privado, solo se puede acceder dentro de la clase externa. Si está decorado con público, se puede acceder desde cualquier lugar; si está decorado con protegido, solo puede estar en el mismo paquete o heredado de la clase externa. Si es el permiso de acceso predeterminado, solo se puede acceder con el mismo paquete.

Clase interna local

Una clase definida en un método o un alcance. La diferencia con la clase interna del miembro es que el acceso de la clase interna local está limitado al método o al alcance.

Al igual que una variante local, no puede haber modificadores estáticos públicos, protegidos, privados.

class People{
    
    
    public People() {
    
    
         
    }
}
 
class Man{
    
    
    public Man(){
    
    
         
    }
     
    public People getWoman(){
    
    
        class Woman extends People{
    
       //局部内部类
            int age =0;
        }
        return new Woman();
    }
}

Clase interna anónima

Es decir, la clase interior sin nombre. Esta definición de clase desaparece de inmediato y no se puede reutilizar. Suele utilizarse para simplificar el código.

El requisito previo para usar clases internas anónimas es: debe heredar una clase principal o implementar una interfaz y, como máximo, heredar una clase principal o implementar una interfaz.

Reglas de uso:

  • Una clase interna anónima no puede ser una clase abstracta, porque cuando el sistema crea una clase interna anónima, inmediatamente creará un objeto de la clase interna anónima. Por lo tanto, no está permitido definir clases internas anónimas como clases abstractas.
  • Una clase interna anónima no puede definir un constructor. Debido a que la clase interna anónima no tiene un nombre de clase, el constructor no se puede definir. Pero una clase interna anónima puede definir un bloque de inicialización, a través del bloque de inicialización de la instancia para completar lo que el constructor necesita para completar.

Código simplificado

abstract class Person {
    
    
    public abstract void eat();
}
 
class Child extends Person {
    
    
    public void eat() {
    
    
        System.out.println("eat something");
    }
}
 
public class Demo {
    
    
    public static void main(String[] args) {
    
    
        Person p = new Child();
        p.eat();
    }
}

En el Childcaso de que la clase en el código anterior solo se use una vez, escribirla como una clase interna puede simplificar el código.

abstract class Person {
    
    
    public abstract void eat();
}
 
public class Demo {
    
    
    public static void main(String[] args) {
    
    
        Person p = new Person() {
    
    
            public void eat() {
    
    
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

interfaz

interface Person {
    
    
    public void eat();
}
 
public class Demo {
    
    
    public static void main(String[] args) {
    
    
        Person p = new Person() {
    
    
            public void eat() {
    
    
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

Siempre que una clase sea abstracta, los métodos de sus subclases se pueden implementar utilizando clases internas anónimas.

Clase interna estática

En comparación con la clase interna miembro, la clase interna estática tiene una más static, es decir, no necesita depender de la clase externa. Además, no puede utilizar variables miembro no estáticas o métodos de clases externas.

public class Test {
    
    
    public static void main(String[] args)  {
    
    
        Outter.Inner inner = new Outter.Inner();
    }
}
 
class Outter {
    
    
    public Outter() {
    
    
         
    }
     
    static class Inner {
    
    
        public Inner() {
    
    
             
        }
    }
}

Algunos beneficios de las clases internas

  1. Cada clase interna puede heredar de forma independiente la implementación de una interfaz, por lo que no importa si la clase externa ha heredado la implementación de una interfaz, no tiene ningún efecto sobre la clase interna.
  2. Es conveniente organizar las clases que tienen una cierta relación lógica entre sí, y pueden ocultarse del mundo exterior.

Referencia

  1. https://zhuanlan.zhihu.com/p/45339875
  2. https://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html
  3. https://www.cnblogs.com/dolphin0520/p/3811445.html

Supongo que te gusta

Origin blog.csdn.net/qq_45934120/article/details/107078597
Recomendado
Clasificación