【JavaSE】Clase interna

Concepto de clase interna

Una clase se puede definir dentro de otra clase o método, la primera se llama clase interna y el segundo se llama clase externa. Las clases internas también son una manifestación de encapsulación. La clase interna y la clase externa comparten el mismo archivo fuente de Java, pero después de la compilación, la clase interna formará un archivo de código de bytes separado.

public class OutClass {
    
    //外部类
	class InnerClass{
    
     //内部类
	}
}

En el código anterior, OutClass es la clase externa y InnerClass es la clase interna. La mayor diferencia entre esta y una clase externa ordinaria es que su objeto de instancia no puede existir solo y debe estar adjunto a un objeto de instancia de una clase externa.

clase interna local

Una clase interna local se define en una ubicación local de la clase externa, generalmente en un método. Tiene acceso a todos los elementos de la clase externa . No se pueden agregar modificadores de acceso porque equivale a una variable local, pero se pueden usar modificaciones finales. El alcance está solo dentro del método o bloque de código en el que está definido.

class Outer{
    
     //外部类
    private int a = 1;//私有属性
    private void fun2(){
    
     //私有方法
        System.out.println("Outer fun2()");
    }
    
    public void fun1(){
    
     
        System.out.println("Outer fun1()");
        
        final class Inner{
    
     //局部内部类
            private int a = 2;
            public void funInner(){
    
    
                System.out.println(a); // 1 外部变量名重名 就近原则
                //Outer.this本质上就是外部类的对象,即哪个对象调用了fun1,Outer.this就指向哪个对象
                System.out.println(Outer.this.a); // 2
                fun2();
            }
        }
        Inner inner = new Inner();
        inner.funInner();
    }
}
public class InnerClass {
    
    
    public static void main(String[] args) {
    
    
        Outer outer = new Outer();
        outer.fun1();
    }
}

Si la clase externa y el miembro de la clase interna local tienen el mismo nombre, se seguirá el principio de proximidad de forma predeterminada. Si desea acceder al miembro de la clase externa, puede usar el nombre de la clase externa.this.nombre del miembro .

Clases internas anónimas (¡¡énfasis en el énfasis!!!)

Una clase interna anónima se refiere a una clase interna sin un nombre de clase y debe declararse utilizando la nueva declaración al crearla. Normalmente, si el parámetro de un método es un tipo de interfaz y la interfaz solo necesita implementarse una vez, entonces podemos definirla en forma de una clase interna anónima.

Instancia de clase interna anónima basada en interfaz:

class Outer1 {
    
    
    private int a = 10;

    public void method() {
    
    
        //基于接口的匿名内部类
        IA person = new IA() {
    
    
            @Override
            public void eat() {
    
    
                System.out.println("正在吃大餐");
            }
        };
        //查看person的运行类型
        System.out.println("person的运行类型:" + person.getClass()); // Outer1$1
        person.eat();
    }
}
//接口
interface IA {
    
    
    void eat();
}

class Person implements IA {
    
    
    @Override
    public void eat() {
    
    
        System.out.println("吃");
    }
}

public class AnonInter {
    
    
    public static void main(String[] args) {
    
    
        Outer1 outer1 = new Outer1();
        outer1.method();
    }
}
IA person = new IA() {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("正在吃大餐");
	}
};

//上面这段代码其实就相当于
class Outer1$1 implements IA {
    
    
	@Override
	public void eat() {
    
    
		System.out.println("正在吃大餐");
	}
}

Cuando el jdk subyacente crea la clase interna anónima Outer1$1, inmediatamente crea una instancia de Outer1$1 y devuelve la dirección a la persona. La clase interna anónima solo se puede usar una vez y luego no se puede volver a usar.

Clases internas anónimas basadas en clases e instancias de clases internas abstractas :

class Outer2 {
    
    
    public void method() {
    
    
        //编译类型:Animal
        //运行类型:Outer2$1
        Animal animal = new Animal("小白"){
    
     //基于类的匿名内部类
            @Override
            public void eat() {
    
    
                System.out.println("匿名内部类重写了eat()");;
            }
        };
        animal.eat();
        System.out.println(animal.getClass()); //animal的运行类型 Outer2$1
        
        //编译类型:Robot
        //运行类型:Outer2$2
        Robot robot = new Robot(){
    
     //基于抽象类的匿名内部类
            @Override
            void run() {
    
    
                System.out.println("正在奔跑");
            }
        };
        robot.run();
        System.out.println(robot.getClass());// robot的运行类型 Outer2$2
    }
}

class Animal implements IC {
    
    
    String name;

    public Animal(String name) {
    
    
        this.name = name;
    }
    public void eat(){
    
    
        System.out.println("Animal 在吃东西");
    }

    @Override
    public void run() {
    
    
        System.out.println("重写的run()");
    }
}

abstract class Robot {
    
     //抽象类
    abstract void run();
}

interface IC {
    
     //接口
    void run();
}

//测试
public class InterClass {
    
    
    public static void main(String[] args) {
    
    
        Outer2 outer2 = new Outer2();
        outer2.method();
    }
}

Detalles de la clase interna anónima
Una clase interna anónima es tanto una definición de clase como un objeto. Desde un punto de vista sintáctico, tiene las características de definir una clase y crear un objeto.

public class AnonClassDatil {
    
    
    public static void main(String[] args) {
    
    
        Outer3 outer3 = new Outer3();
        outer3.fun();
    }
}

class Outer3 {
    
    

    public void fun(){
    
    
        Car car = new Car(){
    
     // 运行类型 Outer3$1
            @Override
            public void speed() {
    
    
                System.out.println("重写了speed()");;
            }
        };
        car.speed(); //动态绑定

        //也可以直接调用
        new Car(){
    
    
            @Override
            public void speed() {
    
    
                System.out.println("直接调用speed()");
            }
        }.speed();
    }
}

class Car {
    
    
    public void speed() {
    
    
        System.out.println("Car speed()");
    }
}

Por favor vea el código a continuación

public class InnerExcise {
    
    
    public static void main(String[] args) {
    
    
        fun(new IQ() {
    
     //当做实参直接传递 简洁高效
            @Override
            public void show() {
    
    
                System.out.println("正在学习Java内部类");
            }
        });
    }
    public static void fun(IQ iq) {
    
     //静态方法 形参是接口类型
        iq.show();
    }
}



interface IQ {
    
    
    void show();
}

Ejercicio:
Hay una interfaz de tono de llamada Bell, que tiene un método de timbre. Hay un teléfono móvil de clase CellPhone, que tiene la función de despertador. "Tarde", y luego pasa otra clase interna anónima para imprimir "Ya tarde".

public class InnerExcise1 {
    
    
    public static void main(String[] args) {
    
    
        CallPhone callPhone = new CallPhone();
        callPhone.alarmClock(new Bell() {
    
     //传递的是实现了Bell接口的匿名内部类
            @Override
            public void ring() {
    
    
                System.out.println("起床了要迟到了");
            }
        });

        callPhone.alarmClock(new Bell() {
    
    
            @Override
            public void ring() {
    
    
                System.out.println("已经迟到了");
            }
        });
    }
}

interface Bell {
    
    
    void ring();
}

class CallPhone {
    
    
    public void alarmClock(Bell bell) {
    
    
        bell.ring(); // 动态绑定
    }
}

clase interna miembro

La clase interna miembro se define en la posición del miembro de la clase externa y no tiene modificaciones estáticas. Puede acceder a todos los miembros de la clase externa, incluidos los miembros privados. Puede agregar cualquier modificador de acceso porque es esencialmente un miembro. En resumen, las clases internas de miembros se refieren a clases internas que no son modificadas por estática y también pueden denominarse clases internas no estáticas.

public class InnerExcise2 {
    
    
    public static void main(String[] args) {
    
    
        Outer5 outer5 = new Outer5();
        outer5.fun();
    }
}

class Outer5 {
    
    
    private int a = 10;
    private class Inner {
    
     // 可以添加任意访问修饰符
        public void say() {
    
    
            System.out.println(a); //可以访问外部类的所有成员,包括私有成员
        }
    }
    public void fun() {
    
    
        Inner inner = new Inner();
        inner.say();
    }
}
public class InnerExcise2 {
    
    
    public static void main(String[] args) {
    
    
        Outer5 outer5 = new Outer5();
        outer5.fun();
        //外部其他类 使用成员内部类的几种方式
        // 第一种 outer5.new Inner() 相当于是把new Inner()当成一个成员
        Outer5.Inner outer51 = outer5.new Inner(); 
        outer51.say();

        Outer5.Inner outer52 = outer5.shawOuter5();
        outer52.say();
    }
}

class Outer5 {
    
    
    private int a = 10;
    public class Inner {
    
     // 可以添加任意访问修饰符
        public void say() {
    
    
            System.out.println(a); //可以访问外部类的所有成员,包括私有成员
        }
    }

    //第二种 定义一个方法 返回一个Inner对象
    public Inner shawOuter5() {
    
    
        return new Inner();
    }
    public void fun() {
    
    
        Inner inner = new Inner();
        inner.say();
    }
}

Si hay miembros con el mismo nombre, se seguirá el principio de proximidad. Si desea acceder a miembros de la clase externa, el método de acceso es el mismo que el anterior, nombre de clase externa.este.nombre de miembro.

clase interna estática

Las definiciones de clases internas estáticas y clases internas de miembros son similares, pero deben modificarse con static , por lo que se denominan clases internas estáticas. La clase interna estática ya no está adjunta a la instancia de Outer, pero es una clase completamente independiente, por lo que no se puede llamar haciendo referencia a Outer.this. Pero puede acceder a los campos estáticos privados y a los métodos estáticos de la clase externa. Si movemos la clase interna estática fuera de la clase externa, perderemos el permiso de acceso privado.

public class StaticInnerClass {
    
    
    public static void main(String[] args) {
    
    
        Outer6 outer6 = new Outer6();
        outer6.fun1();

        //外部其他类访问静态内部类
        //静态内部类可以直接通过类名访问
        Outer6.Fun fun1 = new Outer6.Fun();
        fun1.show();

        //通过定义一个方法返回静态内部类
        Outer6.Fun fun2 = outer6.getFun();
        fun2.show();
    }
}

class Outer6 {
    
    
    private static int a = 99;
    private static String str = "java";
    
    static class Fun {
    
    
        public static int a = 999;
        public void show() {
    
    
            System.out.println(str);
            System.out.println(a); //同名成员遵循就近原则
            System.out.println(Outer6.a); //通过 外部类名.成员名访问
        }
    }

    public void fun1() {
    
    
        Fun fun = new Fun();
        fun.show();
    }
    public Fun getFun() {
    
    
        return new Fun();
    }
}

Solo se puede acceder a las propiedades estáticas y a los métodos de las clases externas estáticas en las clases internas estáticas.

Supongo que te gusta

Origin blog.csdn.net/qq_58032742/article/details/132490956
Recomendado
Clasificación