1. JAVA的内部类

一个类的定义放在另一个类的定义内部,这就是内部类。

根据定义的方式不同,内部类可分为四种:

  • 静态内部类
  • 成员内部类
  • 局部内部类
  • 匿名内部类


内部类可以用private、默认、protectedpublic修饰。而普通类只能用public和默认来修饰。

1.1. 静态内部类

定义在类内部的静态类,就是静态内部类。

静态内部类的实例

public class Outter {
	private static int a = 1;
 	private int b = 2;
 	
    public static class Inner {
 		public void print() {
 			System.out.println(a);
 		}
 	}
    
    public static void main(String[] args) {
    	Outter.Inner innter = new Outter.Inner();
    	innter.print();
   }
    
}

由以上代码可以得出静态内部类的几个特性。

静态内部类的特性:

  • 静态内部类可以访问外部类的所有静态成员(变量和方法), 包括private修饰的成员
  • 静态内部类和一般类一样, 可以定义静态的、动态的变量和方法。
  • 其他类使用、访问静态内部类需要通过外部类.静态内部类的格式,如下所示
    Outter.Inner inner = new Outter.Inner();

Java集合类HashMap内部就有一个静态内部类Entry。Entry是HashMap存放元素的抽象,HashMap 内部维护 Entry 数组用了存放元素,但是 Entry 对使用者是透明的。

像这种和外部类关系密切的,且不依赖外部类实例的,都可以使用静态内部类。

1.2. 成员内部类

定义在类内部的非静态类,就是成员内部类。

class Outter {
    private static int a = 12;
    private int b = 15;

    public class Inner{

        public void print(){

            System.out.println(a);
            System.out.println(b);
        }
    }

    public Inner inner(){
        return new Inner();
    }

    public static void main(String[] args) {
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();
    }
}

由以上代码可以得出成员内部类的几个特性。

成员内部类的特性:

  • 成员内部类可以访问外部类的所有成员,包括使用private修饰的成员。
  • 外部类实例.new:实例化一个内部类必须先实例化外部类,然后通过外部类实例.new 内部类()实例化内部类。如下所示:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
  • 内部类通过外部类.this来引用外部类实例。
  • 成员内部类不能定义静态的方法和变量(final修饰的除外)。

1.3.局部内部类

定义在方法中的类,就是局部内部类。如果一个类只在某个方法中使用,则可以考虑使用局部内部类。

public class Outter {
    private static int a;
    private int b;
    public void test(int one){
        int two = 2;

        class Inner{
            public void print(){
                System.out.println(one);
                System.out.println(two);
            }
        }

        Inner inner = new Inner();
        inner.print();
    }

    public static void main(String[] args) {
        Outter outter = new Outter();
        outter.test(1);
    }
}

由以上代码可以得出局部内部类的几个特性。

局部内部类的特性:

  • 局部内部类不能被publicprivatestatic修饰。 也就是说只能时默认的
  • 该类能访问定义该类的方法中的局部变量,且该变量必须由final修饰。
    (上句话可能有点绕口, 就是这个类在哪定义的,他就能访问那个区域中的局部变量,并且该变量必须由final修饰)
  • 只能在包含该类的方法中,创建该局部内部类的实例。

1.4.匿名类

(要继承一个父类或者实现一个接口、直接使用 new 来生成一个对象的引用)。

匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也是没有 class 关键字,这是因为匿名内部类是直接使用 new 来生成一个对象的引 用。

public abstract class Bird {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public abstract int fly();
}

public class Test {
	public void test(Bird bird) {
		System.out.println(bird.getName() + "能够飞 " + bird.fly() + "米");
	}

	public static void main(String[] args) {
		Test test = new Test();
        //↓↓↓↓↓↓
		test.test(new Bird() {
			public int fly() {
				return 10000;
			}

			public String getName() {
				return "大雁";
			}
		});
	}
}

参考

  • 菜鸟教程https://www.runoob.com/w3cnote/java-inner-class-intro.html
  • java核心知识点整理(内部资料)
  • java编程思想
  • java核心技术卷1(第十版)