[Java object oriented] internal class

Define a Class A in another class B, which class A is called internal class and B is called external class.
The biggest feature of internal classes is that they can directly access private properties and reflect the inclusion relationship of classes.

The essence of an inner class is a class.

Basic syntax:

class External class name { 
    class Internal class name{
    }
}

class Other external class names{
}

Local location (e.g. in method)

1, Local inner class

It is defined in a local location of an external class, such as in a method, and has a class name.

Syntax format:

class External class name {

    public Return value method name(parameter list) {
        // A local inner class is defined in a local location of an outer class, usually a method
        class Internal class name {
        }
        
    }
}

① You can directly access all members in the external class, including private members.

class Outher {
    private int n1 = 100;

    public void m1() {
    	// Inner class
        class Inner {	
        	// Methods of inner classes
            public void f1() {
            	// The inner class can directly access the private members of the outer class
                System.out.println("n1 = " + n1);
            }
        }
    }

}

② Access modifier cannot be added. It is essentially a local variable. Local variables cannot use access modifier. You can use final

Because the final modifier local variables can also be used

class Outher {
    public void m1() {
        // public class Inner {} compilation failed
        // final class Inner {} compilation can pass, but this inner class cannot be inherited
        class Inner{}    // Compilation can be passed, and this internal class can be inherited
        class InnerZi extends Inner {}  // Inheritance of inner class
    }

}

③ Scope: accessible only in the method or code block that defines the inner class.

class Outher {

    {
        class Inner{}   // Internal classes can also be defined in code blocks 
    }

    public void m1() {
        class Inner{}
        Inner inner = new Inner();  // Use internal classes to create internal class objects. Pay attention to the code order

    }

    public void m2() {
        // Inner inner = new Inner();  Another method cannot access internal classes in other methods
    }
}

④ Local inner classes can directly access members of external classes

class Outher {
    private int n1 = 100;
    
    public void m1() {
        class Inner{
            public void f1() {
                System.out.println("n1 = " + n1);   // Accessing member variables of an external class
                m2();   // Accessing member methods of external classes
            }
        }
    }

    public void m2() {}
}

⑤ If the members of the external class and the local internal class have the same name, the principle of proximity is followed by default. If you want to access the members of the external class, you can use: external class name this. Member access

If this keyword is not added, the static member and external class name will be called The essence of this is an external class object. Whoever invokes it is the one who invokes it

class Outher {
	// n1 member variable of external class
    private int n1 = 100;

    public void m1() {
        class Inner{
        	// n1 member variable of inner class
            private int n1 = 200;
            
            public void f1() {
            	// The method is the same
                System.out.println("n1 = " + n1);   // Accessing member variables of internal classes
                System.out.println("n1 = " + Outher.this.n1);   // Accessing member variables of an external class
            }
        }
    }
}

2, Anonymous inner class [super important]

An anonymous inner class is defined in a local location of an outer class, such as a method, and has no class name

The anonymous inner class has no name, but the system will assign a name. The anonymous inner class is also an object.

Syntax format:

new Class name or interface name(parameter list){ 
	// Class body
};

for instance:
Normal interface implementation mode:

interface A {   // One interface
    public void eat();
}

class B implements A {  // Implementation class of interface
    @Override
    public void eat() {
        System.out.println("I like eating");
    }
}

class Outher02 {
    public void method() {
        // Create interface implementation class object
        A a = new B();
        // Calling methods in an interface
        a.eat();
    }
}

Implementation method of anonymous inner class:
If the implementation class is used only once, it will be much more convenient.

interface A {   // One interface
    public void eat();
}

class Fa {  // An ordinary class
    public Fa(String name) {}
    public void test() {}
}

class Outher02 {    // External class
    public void method() {
        // Create interface implementation class object
        A a = new A(){	// Anonymous Inner Class 
            @Override
            public void eat() {
                System.out.println("I like eating");
            }
        };
        // Calling methods in an interface
        a.eat();
    }
}

① The bottom layer of anonymous internal class is that the system creates a class that implements the interface or inherits the parent class, and the system will assign the class name

In the above example, A new class will be generated during compilation, which implements the A interface. The class name of this class is the external class class name + $+ number, for example, Outher02

class Outher02 {    // External class
    public void method() {
        // Create interface implementation class object
        A a = new A(){	// Anonymous Inner Class 
            @Override
            public void eat() {
                System.out.println("I like eating");
            }
        };
        // Calling methods in an interface
        a.eat();
       // View the operation type of variable a
        System.out.println(a.getClass());
    }
}

Through the above code, you can see the following results

Therefore, at the bottom, an anonymous class will be assigned. The name of this class is outler02 $1. The method body of the class is the method body of the anonymous internal class. It should be as follows:

class Outher02$1 implements A {  // The implementation class of the interface created at the bottom of the system
    @Override
    public void eat() {
        System.out.println("I like eating");
    }
}

Then, when creating an object, the reference of the object is returned to variable a, which is the running type of variable a, the a interface, and the compilation type is actually the implementation class of outler02 $1.

② The anonymous inner class can no longer be used once, but the created object can still be used.

class Outher02 {    // External class
    public void method() {
        A a = new A(){ // Anonymous Inner Class 
            @Override
            public void eat() { 
                System.out.println("I like eating");
            }
        };
        a.eat();
        a.eat();
        a.eat();
    }
}

Objects can be used multiple times, but anonymous inner classes can no longer create objects, even new outler02 $1().

③ Anonymous internal classes can implement interfaces or inherit classes. The principle is the same.

The running type and compilation type of the Fu object created here are all Fu classes

class Fu {  // An ordinary class
    public Fu(String name) {}
    public void test() {}
}

class Outher02 {    // External class
    private int n = 100;

    public void method() {
        Fu fu = new Fu("zhangsan");
    }
    
}

However, if the created object is changed into an anonymous internal class object, the running type here is Fu, and the compilation type is an anonymous internal class object. The bottom layer of jdk will also create a one-time class for it, and the class name may be outler02 $2

class Outher02 {    // External class
    private int n = 100;

    public void method() {
        Fu fu = new Fu("zhangsan") {
            
        };
    }

}

After the braces are added, the anonymous inner class is equivalent to inheriting the class of new, so the class generated at the bottom should be:

class Outher02$2 extends Fu{
     public Outher02$2(String name) {
        super(name);
    }
}

If the method of the parent class is overridden in braces, it is also a method that uses the compiled type according to the dynamic binding mechanism.

④ Anonymous inner classes based on abstract classes or interfaces must implement abstract methods

abstract class Fu {  // An abstract class
    public abstract void test();
}

class Outher02 {    // External class
    private int n = 100;

    public void method() {
        // Anonymous Inner Class 
        Fu fu = new Fu() {
        	// Implement abstract methods
            @Override
            public void test() {
            }
        };
    }
}

⑤ You can directly access all members of the external class, including private members

Ibid., Article 1 of the partial internal category

⑥ You cannot add an access modifier. Its essence is a local variable, and its scope is also in the defined method body or code block

Ibid., articles 2 and 3 of the partial internal category

⑦ If the members of the external class and the anonymous internal class have the same name, and the anonymous internal class needs to be accessed, follow the proximity principle. If you want to access the members of the external class, you can use: external class name this. Member access

Ibid., Article 5, partial internal category

Member location (class member location)

3, Member inner class

The inner class of a member is defined in the member position of the outer class, and there is no static modification

Syntax format:

class External class { 
    Access modifier  class Inner class{
    }
}

① You can directly access all members of the external class, including private

A member inner class can be understood as a member of a class. Members in a class can access other members of the class.

class Outher03 {
    
    private int n1 = 300;
    public String name = "zhangsan";
    
    // Member inner class
    class Inner {
        public void say() {
            // You can access all members of the external class, including private
            System.out.println(n1);
            System.out.println(name);
        }
    }
}

② Any access modifier can be added. The essence of the inner class of a member is a member

class Outher03 {

    public class Inner01 {
    }

    protected class Inner02 {
    }

    class Inner03 {
    }

    private class Inner04 {
    }
}

③ The scope of the internal class of a member is the same as that of other members. You can create objects in the external class. If you have permission, you can also use them in other external classes.

// Define class:
public class Person {
    private boolean live = true;
    // If a member's inner class is private, other outer classes cannot create objects of that inner class
    public class Heart {
        public void jump() {
            // Direct access to external class members
            if (live) {
                System.out.println("The heart is beating");
            } else {
                System.out.println("The heart stopped beating");
            }
    	}
	}
	
	public void m1() {
		// The inner class of a member can directly create an object call in the outer class of the class and use it
		Heart heart = new Heart();
		heart.jump();
	}
}

// Define test class:
class InnerDemo {
    public static void main(String[] args) { 
    	// Member internal class in other external classes, you need to create the object of the external class first, and then create the object of the internal class through the object of the external class before you can call and use it
        // Create an external class object
        Person p = new Person();
        // Create internal class object
        Person.Heart heart = p.new Heart();
        // Call internal class methods
        heart.jump();
    }
}
// Output result:
// The heart is beating

④ There are three ways to create objects in other external classes

First: external class name Internal class name variable name = new external class () New member inner class ();

class Outher03 {
    // Member inner class
    public class Inner01 {
    }
}

class Test {
    // Test method for creating class objects inside members
    public void test() {
        Outher03.Inner01 inner01 = new Outher03().new Inner01();
    }
}

The second type: external class name external class variable name = new external class ();
External class name Internal class name internal class variable name = external class variable name new inner class ();

class Outher03 {
    // Member inner class
    public class Inner01 {
    }
}

class Test {
    // Test method for creating class objects inside members
    public void test() {
        Outher03 outher03 = new Outher03();
        Outher03.Inner01 inner01 = outher03.new Inner01();
    }
}

Third: use the get method

class Outher03 {
    // Member inner class
    public class Inner01 {
    }
    
    // get method
    public Inner01 getInner() {
        return new Inner01();
    }
    
}

class Test {
    // Test method for creating class objects inside members
    public void test() {
        Outher03 outher03 = new Outher03();
        Outher03.Inner01 inner = outher03.getInner();
    }
}

⑤ If the external class and internal class members have the same name, the internal class will be accessed according to the proximity principle. If you want to access external class members, you can use: external class name this. member

Ibid., internal category v

4, Static inner class

The static inner class is defined in the member position of the outer class and is decorated with static

class External class {
    Access modifier  static class Inner class {
    }
}

① You can access all static members of an external class, but you cannot directly access non static members

class Outher04 {
    
    private static String name = "lisi";
    private int age = 10;
    
    static class Inner04 {
        // Static internal classes access static members of external classes. Non static members cannot access them directly
        public void m1() {
            System.out.println(name);
        }
        
    }
}

② You can add any access modifier. A static inner class is essentially a static member.

Ibid., Article 2 of the internal category of members

③ Scope: the same as other members. It is the whole class

class Outher04 {
    private static String name = "lisi";

    static class Inner04 {
        public void m1() {
            System.out.println(name);
        }
    }
    
    public void say() {
        // External classes access non static member methods of static internal classes
        Inner04 inner04 = new Inner04();
        inner04.m1();
    }
}
class Outher04 {
    private static String name = "lisi";

    static class Inner04 {
        public static void m2() {
            System.out.println(name);
        }
    }

    public void say02() {
        // The external class accesses the static member methods of the internal class
        Inner04.m2();
    }
}

④ How other external classes access static internal classes:

First: external class name Static internal class name variable name = new external class Internal class ();
It's different from the inner class of members

class Outher04 {
    static class Inner04 {
        public void m1() {
        }
    }
}

class Test02 {
    public void test() {
        Outher04.Inner04 inner04 = new Outher04.Inner04();
    }
}

Second: use the get method
The get method can also be designed to be static, which may be more convenient.

class Outher04 {
    static class Inner04 {
        public void m1() {
        }
    }
    
    // get method
    public Inner04 getInner04(){
        return new Inner04();
    }
}

class Test02 {
    public void test() {
        Outher04 outher04 = new Outher04();
        Outher04.Inner04 inner04 = outher04.getInner04();
    }
}

⑤ If the external class and static internal class members have the same name, the static internal class can be accessed according to the proximity principle. If you want to access external class members, you can use: external class name member

The same as Article 5 of the local internal class, but it is static here and does not need to use this

Keywords: Java Back-end

Added by dud3r on Sat, 05 Feb 2022 09:14:17 +0200