Java中的内部类

java中的内部类分为:静态内部类、成员内部类、局部内部类、匿名内部类java

成员内部类(相似成员变量):ide

public class InnerClassTest {

    public class InnerClassA {
        
    }
}
  • 成员内部类依赖外部类而存在的
  • 成员内部类能够外部类全部的字段,外部类经过成员内部类的引用来访问内部类全部的字段
public class InnerClassTest {

    public int outField1 = 1;
    protected int outField2 = 2;
    int outField3 = 3;
    private int outField4 = 4;

    public InnerClassTest() {
        // 在外部类对象内部,直接经过 new InnerClass(); 建立内部类对象
        InnerClassA innerObj = new InnerClassA();
        System.out.println("建立 " + this.getClass().getSimpleName() + " 对象");
        System.out.println("其内部类的 field1 字段的值为: " + innerObj.field1);
        System.out.println("其内部类的 field2 字段的值为: " + innerObj.field2);
        System.out.println("其内部类的 field3 字段的值为: " + innerObj.field3);
        System.out.println("其内部类的 field4 字段的值为: " + innerObj.field4);
    }

    public class InnerClassA {
        public int field1 = 5;
        protected int field2 = 6;
        int field3 = 7;
        private int field4 = 8;
//        static int field5 = 5; // 编译错误!普通内部类中不能定义 static 属性

        public InnerClassA() {
            System.out.println("建立 " + this.getClass().getSimpleName() + " 对象");
            System.out.println("其外部类的 outField1 字段的值为: " + outField1);
            System.out.println("其外部类的 outField2 字段的值为: " + outField2);
            System.out.println("其外部类的 outField3 字段的值为: " + outField3);
            System.out.println("其外部类的 outField4 字段的值为: " + outField4);
        }
    }

    public static void main(String[] args) {
        InnerClassTest outerObj = new InnerClassTest();
        // 不在外部类内部,使用:外部类对象. new 内部类构造器(); 的方式建立内部类对象
//        InnerClassA innerObj = outerObj.new InnerClassA();
    }
}

静态内部类(相似静态成员变量):this

  • 静态内部类独立于外部类而存在,只要在具备访问权限的地方,经过类名.静态成员名访问:
public class InnerClassTest {
	public int field1 = 1;
    
	public InnerClassTest() {
		System.out.println("建立 " + this.getClass().getSimpleName() + " 对象");
        // 建立静态内部类对象
        StaticClass innerObj = new StaticClass();
        System.out.println("其内部类的 field1 字段的值为: " + innerObj.field1);
        System.out.println("其内部类的 field2 字段的值为: " + innerObj.field2);
        System.out.println("其内部类的 field3 字段的值为: " + innerObj.field3);
        System.out.println("其内部类的 field4 字段的值为: " + innerObj.field4);
    }
	
    static class StaticClass {

        public int field1 = 1;
        protected int field2 = 2;
        int field3 = 3;
        private int field4 = 4;
        // 静态内部类中能够定义 static 属性
        static int field5 = 5;

        public StaticClass() {
            System.out.println("建立 " + StaticClass.class.getSimpleName() + " 对象");
//            System.out.println("其外部类的 field1 字段的值为: " + field1); // 编译错误!!
        }
    }

    public static void main(String[] args) {
	    // 无需依赖外部类对象,直接建立内部类对象
//        InnerClassTest.StaticClass staticClassObj = new InnerClassTest.StaticClass();
		InnerClassTest outerObj = new InnerClassTest();
    }
}
  • 静态内部类只能访问外部类的静态成员
  • 外部类能够访问静态内部类的全部字段

匿名内部类:spa

public class InnerClassTest {

    public int field1 = 1;
    protected int field2 = 2;
    int field3 = 3;
    private int field4 = 4;

    public InnerClassTest() {
        System.out.println("建立 " + this.getClass().getSimpleName() + " 对象");
    }
    // 自定义接口
	interface OnClickListener {
        void onClick(Object obj);
    }

    private void anonymousClassTest() {
        // 在这个过程当中会新建一个匿名内部类对象,
        // 这个匿名内部类实现了 OnClickListener 接口并重写 onClick 方法
        OnClickListener clickListener = new OnClickListener() {
	        // 能够在内部类中定义属性,可是只能在当前内部类中使用,
	        // 没法在外部类中使用,由于外部类没法获取当前匿名内部类的类名,
	        // 也就没法建立匿名内部类的对象
	        int field = 1;
	        
            @Override
            public void onClick(Object obj) {
                System.out.println("对象 " + obj + " 被点击");
                System.out.println("其外部类的 field1 字段的值为: " + field1);
                System.out.println("其外部类的 field2 字段的值为: " + field2);
                System.out.println("其外部类的 field3 字段的值为: " + field3);
                System.out.println("其外部类的 field4 字段的值为: " + field4);
            }
        };
        // new Object() 过程会新建一个匿名内部类,继承于 Object 类,
        // 并重写了 toString() 方法
        clickListener.onClick(new Object() {
            @Override
            public String toString() {
                return "obj1";
            }
        });
    }

    public static void main(String[] args) {
        InnerClassTest outObj = new InnerClassTest();
        outObj.anonymousClassTest();
    }
}
  • new 一个已经存在的类,并选择性实现这个类中一个或多个非final的方法
  • 匿名内部类能够访问外部类的属性,外部类不能访问匿名内部类的属性(由于是匿名内部类,外部类无获取它的类名)

局部内部类(相似匿名内部类):code

  • 比较少使用,声明在方法体/代码块内部。匿名内部类实现能够实现它的功能,同时更为简洁。
public class InnerClassTest {

    public int field1 = 1;
    protected int field2 = 2;
    int field3 = 3;
    private int field4 = 4;

    public InnerClassTest() {
        System.out.println("建立 " + this.getClass().getSimpleName() + " 对象");
    }
    
    private void localInnerClassTest() {
	    // 局部内部类 A,只能在当前方法中使用
        class A {
	        // static int field = 1; // 编译错误!局部内部类中不能定义 static 字段
            public A() {
	            System.out.println("建立 " + A.class.getSimpleName() + " 对象");
                System.out.println("其外部类的 field1 字段的值为: " + field1);
                System.out.println("其外部类的 field2 字段的值为: " + field2);
                System.out.println("其外部类的 field3 字段的值为: " + field3);
                System.out.println("其外部类的 field4 字段的值为: " + field4);
            }
        }
        A a = new A();
        if (true) {
	        // 局部内部类 B,只能在当前代码块中使用
            class B {
                public B() {
	                System.out.println("建立 " + B.class.getSimpleName() + " 对象");
                    System.out.println("其外部类的 field1 字段的值为: " + field1);
                    System.out.println("其外部类的 field2 字段的值为: " + field2);
                    System.out.println("其外部类的 field3 字段的值为: " + field3);
                    System.out.println("其外部类的 field4 字段的值为: " + field4);
                }
            }
            B b = new B();
        }
//        B b1 = new B(); // 编译错误!不在类 B 的定义域内,找不到类 B,
    }

    public static void main(String[] args) {
        InnerClassTest outObj = new InnerClassTest();
        outObj.localInnerClassTest();
    }
}
  • 外部类没法访问局部内部类的字段,局部内部类能够访问外部类的字段
相关文章
相关标签/搜索