Inner classes for Java learning

An inner class, as the name suggests, is a class defined within a class. Inner classes can be divided into member inner classes, local inner classes and anonymous classes, but before introducing, let's talk about what inner classes are used for.
"Think in java" mentioned: The most attractive reason for using inner classes is that each inner class can independently inherit a (interface) implementation, so no matter whether the outer class has inherited a (interface) implementation , has no effect on inner classes.
Inheritance in the traditional sense, for a specific class, only single inheritance can be implemented. If you want multiple inheritance, you can only inherit multiple interfaces. However, for the implementation of interfaces, a class can only implement an interface once. Different ways to achieve, then you can use the inner class. Multiple inner classes inherit the same interface, so that multiple different response events can be made in one class. At the same time, multiple inner classes can inherit multiple different entity classes, thus further improving the solution of multiple inheritance.

member inner class

As a member inner class, there are the following characteristics to explain:

  1. The inner class can freely use the member methods and member variables of the outer class.
  2. The outer class cannot directly modify the member methods or member variables of the inner class. The methods and properties of the inner class cannot be used by the outer class, and are only known within the scope of the inner class.
  3. The inner class instance must be bound to the outer class instance, and the object instantiation of the inner class must be implemented in the outer class or the non-static method of the outer class.
package com.java11.dyp;

public class Demo {
    int i=1;
    inClass inc=new inClass();
    public void outf(){
        System.out.println("这是外部类方法outf()");
        inc.inf();
    }
    class inClass{
        int y=0;            
        inClass(){
            System.out.println("这是内部类构造函数的第"+i+"次调用");
            i++;
        }
        public void inf(){
            System.out.println("修改外部类的属性值i="+i);
        }
    }
    public inClass doit(){
        inc.y=4;            //修改内部类的属性
        return new inClass();   
    }
    public static void main(String[] args) {
        Demo demo=new Demo();
        Demo.inClass in2=demo.doit();   //使用外部类的非静态方法实现实例化
        Demo.inClass in3=demo.new inClass();   //使用外部类对象调用构造函数
    }
}

Let's take an example to illustrate the different ways of implementing the interface methods in the same interface by transforming the internal non-tired up to an interface.

package com.java11.dyp;

interface OutInterface{ 
    public void f();
}

class OuterClass{
    private class InterClass1 implements OutInterface{
        public InterClass1(){
            System.out.println("InterClass1进行了实例化");
        }
        public void f(){
            System.out.println("这是InterClass1调用的f()方法");
        }
    }
    private class InterClass2 implements OutInterface{
        public void f(){
            System.out.println("这是InterClass2调用的f()方法");
        }
        public InterClass2(){
            System.out.println("InterClass2进行了实例化");
        }
    }
    public OutInterface doit1(){
        return new InterClass1();
    }
    public OutInterface doit2(){
        return new InterClass2();
    }
}

public class Demo {
    public static void main(String[] args) {
        OuterClass out=new OuterClass();
        OutInterface oif=out.doit1();
        oif.f();      //实现interClass1中的f()
        oif=out.doit2();
        oif.f();      //实现interClass2中的f()
    }
}

Here is an explanation for the subclass of the above example: in this example, the subclass is defined as private permission, so it can only be accessed by external classes, and other classes cannot operate the subclass. However, because the doit() method is provided in the external class, it can return a reference to an interface. For example, if oif is defined in the code to receive this return value, oif can use the characteristics of up-casting to call the subclass that rewrites the interface f( ) method, which not only hides the specific content of the subclass and the details of the f() method, but also satisfies the use of the interface method, which is also one of the uses of the inner class.

When the properties of the inner class and the outer class have the same name, the use of the this keyword in the inner class

public class Demo {
    private int x=2;
    private class inner{
        private int x=9;
        public void doit(int x){
            System.out.println("参数x="+(++x));
            System.out.println("子类属性x="+(++this.x));
            System.out.println("外部类属性x="+(++Demo.this.x));
        }
    }
    public static void main(String[] args) {
        Demo demo = new Demo();
        inner in=demo.new inner();
        in.doit(4)
    }
}
参数x=5
子类属性x=10
外部类属性x=3

In the above code, the this of the subclass can be used by this.xxx, which is different from the formal parameter and the external class, and the properties of the external class can be called by the external class name.this.XXX.

local class

interface OutInterface2{

}

public class Demo {
    public OutInterface2 doit(final String x){
        class InnerClass2 implements OutInterface2{
            public InnerClass2(String s){
                s=x;
                System.out.println(s);
            }
        }
        return new InnerClass2("doit");
    }
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.doit("Hello World!");
    }
}

As a local inner class, there are several points to note:
1. The inner class is part of the method that defines the class, not part of the outer class, so the inner class cannot be accessed outside the doit() method.
2. The inner class can access the constants of the current code block and all members of this outer class.

anonymous class

Take a look at the following example:

interface OutInterface2{
    public int getValue();
}

public class Demo {
    public OutInterface2 doit(){
        return new OutInterface2(){
            private int i=0;
            public int getValue(){
                return i;
            }
        };
    }
    public static void main(String[] args) {
        Demo demo = new Demo();
        OutInterface2 out=demo.doit();
        System.out.println("i="+out.getValue());

    }
}

Result output:
i=0
may seem inexplicable at first glance, but it is indeed recognized by the Java compiler. Inside the doit() method, a reference to OutInterface2 is first returned, and then a code that defines the inner class is inserted in the return statement. Since the class has no name, the class is called an anonymous inner class. The role of this class is to create an object of an anonymous class that implements the OutInterface2 interface.
It needs to be said here that after the end of the inner class definition, a semicolon needs to be added. This semicolon does not represent the end of the inner class, but represents the creation of the OutInterface2 reference expression.

Finally, let's talk about some other knowledge points of inner classes:

static inner class

Adding static in front of an inner class becomes a static inner class. It has the following features:

  1. Static members can be declared in static inner classes, but static members cannot be declared in non-static inner classes.
  2. Static inner classes cannot use non-static members of outer classes, so static inner classes are relatively rare in program development.
  3. If you create a static inner class object, you don't need an object of its outer class.
    Here is a code example:
public class StaticInnerClass{
    int x=100;
    static class Inner{
        void doitInner(){
                //System.out.println("外部类"+x);    //调用外部类的成员变量x
        }
    }
}

In the above code, println cannot be implemented because non-static members of the outer class cannot be accessed.

Inheritance of inner classes

The inheritance of inner classes is more complicated than that of general classes. To set a special syntax, here is only the format introduction:

public class OutputInnerClass extends ClassA.ClassB{
    public OutputInnerClass(Class a){
        a.super();
    }
}
class ClassA{
    class ClassB{

    }
}

When a class inherits an inner class, the class must be given a constructor with parameters, and the parameters of the constructor must be a reference to the outer class that inherits the inner class, and the a.super() statement is used in the constructor. , which provides the necessary object references for inheritance.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326004921&siteId=291194637