Inner class refers to defining a class inside an external class. The class name does not need to be the same as the folder.
Inner classes are divided into: member inner classes, local inner classes, static nested classes, and anonymous inner classes.
1. Member inner class
Member inner class is the most common inner class. It is defined as located inside another class, in the following form:
class Outter { private int age = 12; class Inner { private int age = 13; public void print() { int age = 14; System.out.println("局部变量:" + age); System.out.println("内部类变量:" + this.age); System.out.println("外部类变量:" + Outter.this.age); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); Outter.Inner in = out.new Inner(); in.print(); } }
Running result:
局部变量:14 内部类变量:13 外部类变量:12
From this example, you can It can be seen that the member inner class is a member of the outer class and can directly use all members and methods of the outer class, even if they are private. Although the member inner class can unconditionally access the members of the outer class, the outer class is not so free to access the members of the member inner class. If you want to access members of a member's inner class in an external class, you must first create an object of the member's inner class, and then access it through a reference to this object:
class Outter { private int age = 12; public Outter(int age) { this.age = age; getInInstance().print(); //必须先创建成员内部类的对象,再进行访问! } private Inner getInInstance() { return new Inner(); } class Inner { public void print() { System.out.println("内部类没同名,所以直接调用外部类成员变量:" + age); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(10); } }
Running results:
内部类没同名,所以直接调用外部类成员变量:10
Inner classes can have private access rights , protected access rights, public access rights and package access rights.
For example, in the above example, if the member inner class Inner is modified with private, it can only be accessed inside the external class. If it is modified with public, it can be accessed anywhere; if it is modified with protected, it can only be accessed within the same package. It can be accessed under the circumstances or when inheriting an external class; if it is the default access permission, it can only be accessed under the same package.
This is a little different from external classes. External classes can only be modified by public and package access permissions.
This is my personal understanding. Since the member inner class looks like a member of the outer class, it can have multiple permission modifications like members of the class. It should be noted that member inner classes cannot contain static variables and methods. Because a member inner class needs to create an outer class before it can create its own
2. Local inner class
A local inner class is a class defined in a method or a scope. The difference between it and a member inner class is that it is local Access to inner classes is limited to methods or scope.
Inner class defined in the method:
class Outter { private int age = 12; public void Print(final int x) { //这里局部变量x必须设置为final类型! class Inner { public void inPrint() { System.out.println(x); System.out.println(age); } } new Inner().inPrint(); } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); out.Print(10); } }
Run result:
10 12
In this example, we move the inner class to the method of the outer class, and then generate an inner class object in the method of the outer class to call the inner class class method. If we need to pass parameters into the method of the external class at this time, then the method parameters of the external class must be defined as final.
In other words, the inner class defined in the method can only access the final type local variables in the method. This is because the local variable defined in the method is equivalent to a constant, and its life cycle exceeds the life cycle of the method running. Since the local variable is set to final, the value of the local variable cannot be changed in the inner class. (I saw different explanations on the Internet here, but I haven’t fully understood it yet==)
Inner classes defined within the scope:
class Outter { private int age = 12; public void Print(final boolean x) { //这里局部变量x必须设置为final类型! if(x){ class Inner { public void inPrint() { System.out.println(age); } } new Inner().inPrint(); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); out.Print(true); } }
3. Static nested classes
Also called static partial classes and nested inner classes, It is an inner class modified as static. An inner class declared as static does not require a connection between the inner class object and the outer class object, which means that we can directly reference outer.inner, that is, there is no need to create an outer class or an inner class.
class Outter { private static int age = 12; static class Inner { public void print() { System.out.println(age); } } } public class test1 { public static void main(String[] args) { Outter.Inner in = new Outter.Inner(); in.print(); } }
You can see that if you use static to make the interior static, then the inner class can only access the static member variables of the outer class, which has limitations.
Secondly, because the inner class is static, Oututter.Inner can be viewed as a whole, and the object of the inner class can be directly new (access static through the class name, it does not matter whether the outer class object is generated or not)
4. Anonymous Internal classes
Anonymous internal classes should be the most commonly used when we write code. Using anonymous internal classes when writing event monitoring code is not only convenient, but also makes the code easier to maintain. The following code is an Android event listening code:
scan_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }); history_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } });
这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。具体位置是这段:
new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }
代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。当然像下面这种写法也是可以的,跟上面使用匿名内部类达到效果相同:
private void setListener() { scan_bt.setOnClickListener(new Listener1()); history_bt.setOnClickListener(new Listener2()); } class Listener1 implements View.OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub } } class Listener2 implements View.OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub } }
这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的,匿名内部类也是不能有访问修饰符和static修饰符的。
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。