【JavaSE】Inner class

Inner class concept

A class can be defined inside another class or a method. The former is called an inner class and the latter is called an outer class. Inner classes are also a manifestation of encapsulation. The inner class and the outer class share the same java source file, but after compilation, the inner class will form a separate bytecode file.

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

In the above code, OutClass is the outer class and InnerClass is the inner class. The biggest difference between it and an ordinary external class is that its instance object cannot exist alone and must be attached to an instance object of an external class.

local inner class

A local inner class is defined in a local location of the outer class, usually in a method. It has access to all elements in the outer class . Access modifiers cannot be added because it is equivalent to a local variable, but final modifications can be used. The scope is only within the method or code block in which it is defined.

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();
    }
}

If the outer class and the local inner class member have the same name, the proximity principle will be followed by default. If you want to access the outer class member, you can use the outer class name.this.member name .

Anonymous inner classes (emphasis on emphasis!!!)

An anonymous inner class refers to an inner class without a class name and must be declared using the new statement when creating it. Normally, if the parameter of a method is an interface type, and the interface only needs to be implemented once, then we can define it in the form of an anonymous inner class.

Interface-based anonymous inner class instance:

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("正在吃大餐");
	}
}

When the underlying jdk creates the anonymous inner class Outer1$1, it immediately creates an instance of Outer1$1 and returns the address to the person. The anonymous inner class can only be used once and then cannot be used again.

Class- based anonymous inner classes and abstract inner class instances:

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();
    }
}

Anonymous inner class details
An anonymous inner class is both a class definition and an object. From a syntactic point of view, it has the characteristics of defining a class and creating an object.

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()");
    }
}

Please see the code below

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();
}

Exercise:
There is a ringtone interface Bell, which has a ring method. There is a mobile phone class CellPhone, which has the function of alarm clock. Late", and then pass in another anonymous inner class to print "Already late".

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(); // 动态绑定
    }
}

member inner class

The member inner class is defined in the member position of the outer class and has no static modification. It can access all members of the outer class, including private members. You can add any access modifiers because it is essentially a member. In short, member inner classes refer to inner classes that are not modified by static, and can also be called non-static inner classes.

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();
    }
}

If there are members with the same name, the proximity principle will be followed. If you want to access external class members, the access method is the same as above, external class name.this.member name.

static inner class

The definitions of static inner classes and member inner classes are similar, but they need to be modified with static , so they are called static inner classes. The static inner class is no longer attached to the instance of Outer, but is a completely independent class, so it cannot be called by referring to Outer.this. But it can access the private static fields and static methods of the Outer class. If we move the static inner class outside the Outer class, we will lose the permission to access private.

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();
    }
}

Only static properties and methods of static outer classes can be accessed in static inner classes

Guess you like

Origin blog.csdn.net/qq_58032742/article/details/132490956