内部类,指当前类定义在一个类的内部或方法的内部。内部类也是封装的一种体现。
内部类大致分为:实例内部类,静态内部类,普通内部类(不常用,定义在方法内部,很少使用),匿名内部类。下面我们来介绍比较常用的三种。
匿名内部类
如名称所说,这样一个类并没有名字。它与我们上次介绍的接口密切相关,大家可以观察如下代码。
interface A{ void testA(); } public class Test { public static void main(String[] args) { new A(){ @Override public void testA() { System.out.println("hello!"); } }.testA(); } }
我们能观察到这样一个类,他本质上没有名字。这个类实现了A的接口,并重写了A接口中的方法。我们可以在这个类的大括号外面用.进行调用。
实例内部类
未被static修饰的成员内部类。
public class OuterClass { public int a; class InnerClass{ public int data=4; public void test(){ System.out.println("hello!"); } } }
这个InnerClass类存在于OuterClass类当中,我们称前者为实例内部类。那么我们该如何去调用它呢?我们需要通过外部类对象的引用调用内部类对象,这个内部类对象依赖于外部类对象,先有外部类,再有实例内部类。
OuterClass.InnerClass innerClass=new OuterClass().new InnerClass();
在内部队当中,我们不能直接用static修饰一个普通成员变量。因为static虽然不依赖于任何对象,却定义在一个需要依赖对象的类当中。
当内部类和外部类变量名相同时,优先访问内部类的,内部类没有再找外部类的。
public class OuterClass { public int a=5; class InnerClass{ public int a=10; public void test(){ System.out.println("hello!"); } } public static void main(String[] args) { OuterClass.InnerClass innerClass=new OuterClass().new InnerClass(); System.out.println(innerClass.a); } }
那么当相同时,我们如何直接访问外部类的普通成员变量呢?我们可以通过外部类名.this.的方法
实力内部类当中是包含外部类的this的。
静态内部类
用static修饰实例内部类,就是我们现在要介绍的静态内部类。他的创建并不依赖于外部类对象,我们可以直接创建。其他使用时的方法基本和实例内部类相同。
public class OuterClass { public int a=5; static class InnerClass{ public void test(){ System.out.println("hello!"); } } public static void main(String[] args) { OuterClass.InnerClass innerClass=new OuterClass.InnerClass(); } }