This is the 8th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

The inside of one thing contains another thing. A class that contains another class is called an inner class, and a class that contains it is called an outer class.

For example, the relationship between the body and the heart; The relationship between the car and the engine.

The heart and engine are only useful in the body and the car. The same goes for inner classes.

Classification:

1. Member inner class;

2. Local inner classes (including anonymous inner classes);

1. Member inner classes

/* Modifier class Outer class name {modifier class inner class name {...... }... } * /
public class Outer {
    private String name;

    public class Inter{
        public void InterMethod(a){
            System.out.println("Internal method");
            System.out.println("Name:" + name);   // Member inner classes can access external class attributes}}public void fun1(a){
        Inter in = newInter(); in.InterMethod(); }}Copy the code

After compilation, the class file for this class is saved on disk

How inner classes are used

It can be used directly from an external class as a new object.

Access in other classes:

1. Indirection: use an inner class in an outer class’s method, and call the method on a new outer class in another class;

/** * Other classes use inner classes */
public class OuterDemo1 {
    public static void main(String[] args) {
        Outer out = newOuter(); out.fun1(); }}Copy the code

2. Create inner classes directly

Formula: external class name. Inner class name Object name = new inner class name ().new inner class name ();

public class OuterDemo2 {
    public static void main(String[] args) {
        Outer.Inter in = new Outer().new Inter(a); in.InterMethod(); }}Copy the code

Problem: How to output the corresponding value when an attribute with the same name appears on an external class, an inner class, and an inner class method body?

Solution:

public class OuterDemo3 {

    private String name ="Outside";

    class Inter{
        private String name = "Within";
        public void interMethod(a){
            String name = "Method";
            System.out.println(name);   // Output: method, proximity principle
            System.out.println(this.name);   // Output: inside
            System.out.println(OuterDemo3.this.name);    // Output: external}}}Copy the code

2. Local inner classes

Define a class in a method body that cannot be used outside of the method (so other classes cannot use local inner classes)

Popularity:

Rules for using permission modifiers:

public > protected > (default) > private

1. External classes: can use public/(defautl) modifier

Public/protected/(default)/private

3. Local inner classes: Write nothing

public class Test {

    public void fun(a){
        final int num = 100;
        class Fun{
            private void fun2(a){
                System.out.println(num);
            }
        }
        Fun fun = newFun(); fun.fun2(); }}Copy the code

Question: Why must final be used to access a local variable of a method?

Causes (lifecycles in nature) :

1. Objects from the inner class new are in heap memory;

2. Local variables follow methods in stack memory;

3. After the method is run, the stack is immediately removed, and local variables disappear;

4. New objects, however, persist in the heap until garbage collection;

5. Therefore, the memory must be copied to the constant pool to save the continued use.

3. Anonymous Inner classes (important)

Normally, to use an interface method, we have to define the implementation class of the interface -> override all the abstract methods of the interface -> new implementation class to use.

If the implementation class of the interface is to be used only once, then the implementation class definition can be omitted and anonymous inner classes can be used instead.

interface

public interface MyInteface {
    void method(a);
}
Copy the code

Use anonymous Inner classes

/** * format: * interface name object name = new interface name (){* // override all abstract methods *}; * /
public class AnonymityTest2 {
    public static void main(String[] args) {
        MyInteface my = new MyInteface(){
            @Override
            public void method(a) {
                System.out.println("Anonymous inner class methods"); }}; my.method(); }}Copy the code

Many people may have a misunderstanding at first: is it not [anonymous inner class]? MyInteface my = new MyInteface(){… } Isn’t there a name?

First, for “new MyInteface(){… };” The resolution:

1). New represents the action of object creation;

2). Interface name [anonymous inner class] Interface to be implemented;

3.) {… } This is the content of the anonymous inner class, which overrides all the abstract methods of the interface

It’s naked. It really doesn’t have a name.

MyInteface my = new MyInteface(){… My in} is the name of the object that allows you to call anonymous class methods.

Ps: Anonymous inner class, anonymous object

1. [Anonymous inner class] is a class that can be used only once when creating an object. It is usually used to write an implementation class for an interface.

If you want to create an object multiple times and the contents of the class are the same, it is more convenient to define a separate implementation class.

public class AnonymityTest2 {
    public static void main(String[] args) {
        MyInteface my1 = new MyInteface(){
            @Override
            public void method(a) {
                System.out.println("Anonymous inner class methods"); }}; my1.method(); MyInteface my2 =new MyInteface(){
            @Override
            public void method(a) {
                System.out.println("Anonymous inner class methods"); }}; my2.method(); }}Copy the code

2. [Anonymous object] means that the method can be called only once.

If you want to call a method multiple times on the same object, give the object a name.

new MyInteface(){
            @Override
            public void method1(a) {
                System.out.println("Anonymous inner class method 1");
            }

            @Override
            public void method2(a) {
                System.out.println("Anonymous inner class method 2");
            }
        }.method1();
        
        new MyInteface(){
            @Override
            public void method1(a) {
                System.out.println("Anonymous inner class method 1");
            }
            @Override
            public void method2(a) {
                System.out.println("Anonymous inner class method 2");
            }
        }.method2();
Copy the code

3. It’s not the same thing

[anonymous inner class] is omitted < implementation class/subclass >

[Anonymous object] is omitted < object name >

It’s not the same thing.

public class AnonymityTest {
    public static void main(String[] args) {
        fun1();
    }

    private static void fun1(a) {
        // For Thread, this is an anonymous object.
        // For Runnable, this is an anonymous inner class.
        new Thread( new Runnable(){
            @Override
            public void run(a) { } }).start(); }}Copy the code