Xiaobai learns Java: internal classes

Xiaobai learns Java: internal classes

An internal class is a form of encapsulation. It is a class defined in a class or interface.

Classification of internal classes

Member inner class

That is, the defined inner class is an ordinary member (non static) of the outer class, as follows:

public class Outer {
    class Inner{
        private String id = "夏天";

        public String getId() {
            return id;
        }
    }

    public Inner returnInner(){
        return new Inner();
    }
    public void show(){
        Inner in = new Inner();
        System.out.println(in.id);
    }
}

Through the above simple example, we can draw the following points:

We can see that we use inner classes like normal classes, but in fact, inner classes have many mysteries that are worth learning. As for the use of internal classes, let's not talk about it for the time being. It's not too late to learn its syntax first. Let's try to create this inner object in another class:

class OuterTest{
    public static void main(String[] args) {
        //!false:Inner in = new Inner();
        Outer o = new Outer();
        o.show();
        Outer.Inner in = o.returnInner();
        //!false: can't access --System.out.println(in.id);
        System.out.println(in.getId());
    }
}

Oh, that's interesting. We tested the inner class we defined before again in another class outertest. The results showed that there were very obvious changes. We fell into meditation:

Speaking of this, we can probably guess that the existence of internal classes can well hide part of the associated code, and realize the sentence: you can look at what I want you to see, and there is no door for what you don't want you to see.

Link to external class

In fact, when we analyzed the source code of ArrayList before, we had come into contact with internal classes. When we studied iterator design patterns, we also experienced the mysteries of inner classes. Next, I will analyze and learn from the simple case of implementing iterator mode through an internal class in Java programming ideas: first, define a "selector" interface:

interface Selector {
    boolean end();//判断是否到达终点
    void next();//移到下一个元素
    Object current();//访问当前元素
}

Then, define a sequence class sequence:

public class Sequence {
    private Object[] items;
    private int next = 0;
    //构造器
    public Sequence(int size) {
        items = new Object[size];
    }
    public void add(Object x) {
        if (next < items.length) {
            items[next++] = x;
        }
    }
    //该内部类可以访问外部类所有成员(包括私有成员)
    private class SequenceSelector implements Selector {
        private int i = 0;
        @Override
        public boolean end() {
            return i == items.length;
        }
        @Override
        public void next() {
            if (i < items.length) {
                i++;
            }
        }
        @Override
        public Object current() {
            return items[i];
        }
    }
    //向上转型为接口,隐藏实现的细节
    public Selector selector() {
        return new SequenceSelector();
    }
}

Let's take a look at the specific test methods:

    public static void main(String[] args) {
        Sequence sq = new Sequence(10);
        for (int i = 0; i < 10; i++) {
            sq.add(Integer.toString(i));
        }
        //产生我们设计的选择器
        Selector sl = sq.selector();

        while (!sl.end()) {
            System.out.print(sl.current() + " ");
            sl.next();
        }
    }

. New and this

Let's slightly modify the original outer:

public class Outer {
    String id = "乔巴";
    class Inner{
        private String id = "夏天";

        public String getId() {
            return id;
        }
        public String getOuterId(){
            return Outer.this.id;
        }
        public Outer returnOuter(){
            return Outer.this;
        }
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        System.out.println(o.new Inner().getId());//夏天
        System.out.println(o.new Inner().getOuterId());//乔巴
    }
}

Let's test a wave:

    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
        System.out.println(oi.getId());//夏天
        Outer o = oi.returnOuter();
        System.out.println(o.id);//乔巴
    }

Local inner class

Method scope inner class

That is, create a complete class within the method scope.

public class Outer {
    public TestOuter test(final String s){
        class Inner implements TestOuter{
            @Override
            public void testM() {
                //!false: s+="g";
                System.out.println(s);
            }
        }
        return new Inner();
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        o.test("天乔巴夏").testM();//天乔巴夏
    }
}
interface TestOuter{
    void testM();
}

There are two points to note:

Internal classes within any scope

Internal classes can be defined in any scope:

public class Outer {
    public void test(final String s,final int value){
        final int a = value;
        if(value>2){
            class Inner{
                public void testM() {
                    //!false: s+="g";
                    //!false: a+=1;
                    System.out.println(s+","+a);
                }
            }
            Inner in = new Inner();
            in.testM();
        }
        //!false:Inner i = new Inner();
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        o.test("天乔巴夏",3);
    }
}

It should also be noted that:

Static inner class

That is, the member inner class decorated with static belongs to the class, that is, it has no reference to the outer class.

public class Outer {
    static int a = 5;
    int b = 6;
    static class Inner{
        static int value;
        public void show(){
            //!false System.out.println(b);
            System.out.println(a);
        }
    }
}
class OuterTest {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer.Inner();
        oi.show();
    }
}

It should be noted that:

Anonymous Inner Class

The name of this type of internal class is strange. Let's take a look at a code that violates our cognition:

public class Outer {
    public InterfaceInner inner(){
    //创建一个实现InterfaceInner接口的是实现类对象
        return new InterfaceInner() {
            @Override
            public void show() {
                System.out.println("Outer.show");
            }
        };
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        o.inner().show();
    }
}
interface InterfaceInner{
    void show();
}

It's really strange. At first glance, interfaceinner is an interface, and why does the word new interfaceinner () appear in the inner method of outer class? Can't an interface create an instance object?

Indeed, this is a use of anonymous internal classes. In fact, the inner method returns the implementation class object that implements the interface method. We can see that the end of the semicolon represents a complete expression, but the expression contains the interface implementation, which is a little long. Therefore, the syntax of the above anonymous inner class is actually a simplified form of the following form:

public class Outer {   
    class Inner implements InterfaceInner{
        @Override
        public void show(){
            System.out.println("Outer.show");
        }
    }
    public InterfaceInner inner(){ 
        return new Inner();  
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        o.inner().show();
    }
}
interface InterfaceInner{
    void show();
}

Not only interfaces, ordinary classes can also be used as "interfaces":

public class Outer {
    public OuterTest outerTest(int value) {
        //参数传给匿名类的基类构造器
        return new OuterTest(value) {
            
            @Override
            public int getValue() {
                return super.getValue() * 10;
            }
        };
    }
    public static void main(String[] args) {
        Outer o = new Outer();
        System.out.println(o.outerTest(10).getValue());//100
    }
}
class OuterTest {
    public int value;
    OuterTest(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
}

It should be noted that:

Inheritance of inner classes

Inner classes can be inherited, but they have some origins from our ordinary class inheritance. Specifically:

public class Outer {
    class Inner{
        private int value = 100;
        Inner(){
        }
        Inner(int value){
            this.value = value;
        }
        public void f(){
            System.out.println("Inner.f "+value);
        }
    }
}
class TestOuter extends Outer.Inner{
    TestOuter(Outer o){
        o.super();
    }
    TestOuter(Outer o,int value){
        o.super(value);
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        TestOuter tt = new TestOuter(o);
        TestOuter t = new TestOuter(o,10);
        tt.f();
        t.f();
    }
}

What we can find is:

What's the use of inner classes

What you can see is that the implementation details inside the inner class can be well encapsulated. Moreover, there are multiple implementations of interfaces in Java. Although it makes up for Java's "not supporting multiple inheritance" to a certain extent, the existence of internal classes makes it better. Take the following example:

//假设A、B是两个接口
class First implements A{
    B makeB(){
        return new B() {
        };
    }
}

This is a simple example of implementing interface functions through anonymous inner classes. For interfaces, we can do this through the following, because one class in Java can implement multiple interfaces:

class First implements A,B{
}

However, in addition to interfaces, ordinary classes and abstract classes can define independent internal classes to inherit and implement separately, and use internal classes to make "multiple inheritance" more perfect.

Because many of the following contents have not been involved and learned, the summary is relatively simple, and there is no particularly in-depth and real scene simulation. Later, we will make a systematic summary when we have time. If there are narrative errors, we also hope to criticize the pointer in the comment area and make common progress. Reference: Java programming ideas https://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class?r=SearchResults

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>