Java各种内部类解析

-目录-

内部类

Java Class是一种行为规范,它不只是可以定义在packge中,还可以定义在方法里,分支结构里…

按照定义的位置可以分为:

成员内部类

成员内部类定义在外部大的Class内。成员内部类的特点:

public class TestC {
    int outA = 1;

    public static void main(String[] args) {
        TestC testC = new TestC();
        Ex1 ex1 = testC.new Ex1();
        Ex2 ex2 = testC.new Ex2();
        // 外部类改变内部类的值(继承来的)
        ex1.num = 1;
        ex2.num = 2;
        ex1.sonFunc();
        ex2.sonFunc();
        ex1.reOuterClass().outA = 2;
    }

    class Ex1 extends Son1Class {

        // 内部类获取到外部类的引用
        TestC reOuterClass() {
            return TestC.this;
        }

        // 内部类更改外部类变量
        void changeNum() {
            outA = 2;
        }
    }

    class Ex2 extends Son2Class {}
}

class Son1Class {
    int num;
    void sonFunc() {}
}

class Son2Class {
    int num;
    void sonFunc() {}
}

局部内部类

作用域很小,只在定义区域有效,用于实现某些私有的功能

public class TestC {
    public static void main(String[] args) {
        // 类似结构体
        class InnerClass {
            int age;
            String name;

            InnerClass(int age, String name) {
                this.age = age;
                this.name = name;
            }

            void sayString() {
                System.out.println("My profile is" +
                        "age=" + age +
                        ", name='" + name);
            }
        }
        InnerClass peopleA = new InnerClass(18, "Jack");
        InnerClass peopleB = new InnerClass(25, "Bob");
        InnerClass[] people = {peopleA, peopleB};
        for (InnerClass p : people) {
            p.sayString();
        }
    }
}

匿名内部类

无名,创建即使用。匿名内部类创建时和原类有中类似继承的微妙关系。匿名类可以覆写原类的方法,可以添加变量和原类没有的方法,但都只在创建时的作用域有效,创建完成后就访问不到了。

public class TestC {
    void getClass(TestD testClass) {
        // 访问的是原类中的num
        System.out.println(testClass.num);
        testClass.sayString();
        testClass.sayString2();
        // testClass.sayString3();错误,不能访问到

    }

    public static void main(String[] args) {
        int a = 0;
        new TestC().getClass(new TestD() {
            // 可以定义任何变量,但是这个变量只在当前创建类时的作用域有效
            int num = 2;
			
            // a=1;错误,不可更改局部变量,但可以访问。这体现了与JAVA闭包的不同
            a;
              
            // 如果要定义同名方法就要覆写,类似于子类的关系,不能创建新的方法
            @Override
            public void sayString2() {
                System.out.println("The num is " + num);
                System.out.println("Anonymous function OK");
            }

            // 可以定义原类中没有的方法,但是当匿名类作为参数传入时,是没有意义的,访问不到
            // 因为需要这个类的方法是基于原来的类TestD考虑的,没有考虑到你新增方法,
            public void sayString3() {
            }

        });
    }
}


class TestD {
    int num = 1;

    void sayString() {
        System.out.println("The num is " + num);
        System.out.println("Class function OK");
    }

    void sayString2() {

    }
}

//输出
//1
//The num is 1
//Class function OK
//The num is 2
//Anonymous function OK

静态内部类

使用了static修饰的内部类即为静态内部类,和普通的成员内部类最大的不同是:

public class TestC {
    int num;

    // 静态内部类
    static class InnerClass {
        int age;
        String name;
        // TestC testC = TestC.this;错误
        // num=1;错误
    }
}

class TestD {
    // 无需要先行new TestC
    TestC.InnerClass innerClass = new TestC.InnerClass();
}
© 2019 - 2023 · YuYoung's Blog