2021-03-12

Inner class

1 Overview

1. What is an internal class?

Define a class A in another class B, the class A inside is called the inner class , and B is called the outer class .

2. Why declare inner classes?

When there is a part inside a thing that needs a complete structure to describe, and this complete internal structure only provides services for external things and is not used alone in other places, then the entire internal complete structure is best to use internal classes .

And because the inner class is inside the outer class, it can directly access the private members of the outer class.

3. What are the forms of internal classes?

According to the position of the internal class declaration (like the classification of variables), we can be divided into:

(1) Member inner class:
  • Static member inner class
  • Non-static member inner class
(2) Local inner class
  • Named local inner class
  • Anonymous inner class

2 Static inner class

Syntax format:

【修饰符】 class 外部类{
    
    
    【其他修饰符】 static class 内部类{
    
    
    }
}

Characteristics of static inner classes:

  • Like other classes, it is just another complete class structure defined in the external class
    • You can inherit your own parent class you want to inherit, and implement the parent interface you want to implement, regardless of the parent class and parent interface of the external class
    • You can declare properties, methods, constructors and other structures in static inner classes, including static members
    • Can be modified with abstract, so it can also be inherited by other classes
    • Can use final modification, which means that it cannot be inherited
    • After compilation, there is its own independent bytecode file, but the internal class name is prefixed with the external class name and the $ symbol.
  • Different from the external class, it can allow four permission modifiers: public, protected, default, private
    • External classes only allow public or default
  • Only static members of outer classes can be used in static inner classes
    • Non-static members of external classes cannot be used in static inner classes
  • Outside of the outer class, you can create static inner class objects without passing the objects of the outer class.
  • If there are variables in the inner class with the same name as the static member variables of the outer class, you can use "external class name." to distinguish

Sample code:

public class TestInner{
    
    
    public static void main(String[] args){
    
    
    	Outer.Inner in= new Outer.Inner();
    	in.inMethod();
    	
    	Outer.Inner.inTest();
        
        Outer.Inner.inFun(3);
    }
}

class Outer{
    
    
	private static int a = 1;
	private int b = 2;
	protected static class Inner{
    
    
		static int d = 4;//可以
		void inMethod(){
    
    
			System.out.println("out.a = " + a);
//			System.out.println("out.b = " + b);//错误的
		}
		static void inTest(){
    
    
			System.out.println("out.a = " + a);
		}
        static void inFun(int a){
    
    
			System.out.println("out.a = " + Outer.a);
            System.out.println("local.a = " + a);
		}
	}
}

In fact, strictly speaking (in "The Java Language Specification" edited by James Gosling et al.) static inner classes are not inner classes, but similar to the concept of nested classes in C++, and outer classes are just a kind of namespace for static inner classes. It’s just a qualified name. Therefore, the inner classes in the interface are usually not called inner classes, because the inner members in the interface are implicitly static (that is, public static). For example: Map.Entry.

3 Non-static member inner class

Syntax format:

【修饰符】 class 外部类{
    
    
    【修饰符】 class 内部类{
    
    
    }
}

Characteristics of non-static inner classes:

  • Like other classes, it is just another complete class structure defined in the external class
    • You can inherit your own parent class you want to inherit, and implement the parent interface you want to implement, regardless of the parent class and parent interface of the external class
    • You can declare properties, methods, constructors, and other structures in non-static inner classes, but you are not allowed to declare static members , but you can inherit the static members of the parent class, and you can declare static constants .
    • Can be modified with abstract, so it can also be inherited by other classes
    • Can use final modification, which means that it cannot be inherited
    • After compilation, there is its own independent bytecode file, but the internal class name is prefixed with the external class name and the $ symbol.
  • Different from the external class, it can allow four permission modifiers: public, protected, default, private
    • External classes only allow public or default
  • You can also use all members of the outer class in a non-static inner class , even if it is private
  • Non-static inner classes cannot be used in static members of outer classes
    • Just as the non-static member variables and non-static methods of this class cannot be accessed in the static method
  • Outside of the outer class, the object of the outer class must be passed to create the object of the non-static inner class
    • Therefore, there are two this objects in the method of the non-static inner class, one is the this object of the outer class, and the other is the this object of the inner class

Sample code:

public class TestInner{
    
    
    public static void main(String[] args){
    
    
    	Outer out = new Outer();
    	Outer.Inner in= out.new Inner();
    	in.inMethod();
    	
    	Outer.Inner inner = out.getInner();
    	inner.inMethod();
    }
}
class Father{
    
    
	protected static int c = 3;
}
class Outer{
    
    
	private static int a = 1;
	private int b = 2;
	protected class Inner extends Father{
    
    
//		static int d = 4;//错误
		int b = 5;
		void inMethod(){
    
    
			System.out.println("out.a = " + a);
			System.out.println("out.b = " + Outer.this.b);
			System.out.println("in.b = " + b);
			System.out.println("father.c = " + c);
		}
	}
	
	public static void outMethod(){
    
    
//		Inner in = new Inner();//错误的
	}
	public Inner getInner(){
    
    
		return new Inner();
	}
}

4 Local inner class

Syntax format:

【修饰符】 class 外部类{
    
    
    【修饰符】 返回值类型  方法名(【形参列表】){
    
    final/abstractclass 内部类{
    
    
    	}
    }    
}

The characteristics of the local inner class:

  • Like the external class, it is just another complete class structure defined in a method of the external class
    • You can inherit your own parent class you want to inherit, and implement the parent interface you want to implement, regardless of the parent class and parent interface of the external class
    • You can declare properties, methods, constructors and other structures in the local inner class, but do not include static members, unless it is a static constant inherited from the parent class
    • Can be modified with abstract, so it can also be inherited by other inner classes behind it in the same method
    • Can use final modification, which means that it cannot be inherited
    • After compilation, there is its own independent bytecode file, but the internal class name is prefixed with the external class name, $ symbol, and number.
      • The number here is because there are local inner classes with the same name in different methods in the same outer class
  • Unlike the member inner class, it cannot have permission modifiers, etc. in front of it
  • Local inner classes have scopes like local variables
  • Whether the static or non-static members of the external class can be accessed in the local inner class depends on the method in which it is located
  • The local constant of the method can also be used in the local inner class, that is, the local variable declared with final
    • After JDK1.8, if a local variable is used in a local internal class, it will automatically add final

Sample code:

class Outer{
    
    
	private static int a = 1;
	private int b = 2;
	
	public static void outMethod(){
    
    
		final int c = 3;
		class Inner{
    
    
			public void inMethod(){
    
    
				System.out.println("out.a = " + a);
//				System.out.println("out.b = " + b);//错误的,因为outMethod是静态的
				System.out.println("out.local.c = " + c);
			}
		}
		
		Inner in = new Inner();
		in.inMethod();
	}
	
	public void outTest(){
    
    
		final int c = 3;
		class Inner{
    
    
			public void inMethod(){
    
    
				System.out.println("out.a = " + a);
				System.out.println("out.b = " + b);//可以,因为outTest是飞静态的
				System.out.println("method.c = " + c);
			}
		}
		
		Inner in = new Inner();
		in.inMethod();
	}
	
}

5 Anonymous inner class

1. Introduce

When we are in the development process, we need to use an object of an abstract class subclass or an object of an interface implementation class, and only one object is created, and the logic code is not complicated. So how did we do it in the first place?

(1) Write a class, inherit this parent class or implement this interface

(2) Override the method of the parent class or parent interface

(3) Create an object of this subclass or implementation class

E.g:

public interface Runnable{
    
    
    public abstract void run();
}
//声明接口实现类
public class MyRunnable implements Runnable{
    
    
    public void run(){
    
    
        while(true){
    
    
            System.out.println("大家注意安全");
            try
            	Thread.sleep(1000);
            }catch(Exception e){
    
                    
            }
        }
    }
}
public class Test{
    
    
    public static void main(String[] args){
    
    
        //如果MyRunnable类只是在这里使用一次,并且只创建它的一个对象
        //分开两个.java源文件,反而不好维护
        Runnable target = new MyRunnable();
        Thread t = new Thread("安全提示线程",target);
        t.start();
    }
}

2. Grammar format

new 父类(【实参列表】){
    
    
    重写方法...
}
//()中是否需要【实参列表】,看你想要让这个匿名内部类调用父类的哪个构造器,如果调用父类的无参构造,那么()中就不用写参数,如果调用父类的有参构造,那么()中需要传入实参
new 父接口(){
    
    
    重写方法...
}
//()中没有参数,因为此时匿名内部类的父类是Object类,它只有一个无参构造

An anonymous inner class is a class without a name, so a unique object is created when the class is declared.

note:

An anonymous inner class is a special kind of local inner class, but it has no name. All local inner class restrictions apply to anonymous inner classes. E.g:

  • Whether the non-static member variables of the outer class can be used in the anonymous inner class, to see whether the method is static
  • If you need to access the local variables of the current method in the anonymous inner class, the local variables need to be final

Thinking: What can this object do?

Answer: (1) call a method (2) assign a value to the parent class/parent interface variable, use this object through polymorphic reference (3) as the actual parameter of a method call

3. Usage 1: The object of the anonymous inner class directly calls the method

interface A{
    
    
	void a();
}
public class Test{
    
    
    public static void main(String[] args){
    
    
    	new A(){
    
    
			@Override
			public void a() {
    
    
				System.out.println("aaaa");
			}
    	}.a();
    }
}
class B{
    
    
	public void b(){
    
    
		System.out.println("bbbb");
	}
}
public class Test{
    
    
    public static void main(String[] args){
    
    
    	new B(){
    
    
    		public void b(){
    
    
    			System.out.println("ccccc");
    		}
    	}.b();
    	
    }
}

4. Usage 2: Use the variable polymorphism of the parent class or parent interface to reference the object of the anonymous inner class

interface A{
    
    
	void a();
}
public class Test{
    
    
    public static void main(String[] args){
    
    
    	A obj = new A(){
    
    
			@Override
			public void a() {
    
    
				System.out.println("aaaa");
			}
    	};
    	obj.a();
    }
}
class B{
    
    
	public void b(){
    
    
		System.out.println("bbbb");
	}
}
public class Test{
    
    
    public static void main(String[] args){
    
    
    	B obj = new B(){
    
    
    		public void b(){
    
    
    			System.out.println("ccccc");
    		}
    	};
    	obj.b();
    }
}

5. Usage 3: Objects of anonymous inner classes as actual parameters

interface A{
    
    
	void method();
}
public class Test{
    
    
    public static void test(A a){
    
    
    	a.method();
    }
    
    public static void main(String[] args){
    
    
    	test(new A(){
    
    

			@Override
			public void method() {
    
    
				System.out.println("aaaa");
			}
    		
    	});
    }   
}

Guess you like

Origin blog.csdn.net/qq_37698495/article/details/114710371