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