详情参考这篇文章Java内部类详解
。 内部类就是,在一个类里放了另一个类。
为什么要放一个类进另一个类呢?
最根本的原因:为了完善Java缺少的“多根继承”的概念。
内部类有四种:
一、成员内部类
class outSide{ private int number = 1; class innerSide{ private int number= 2; public void method(){ int number = 3; System.out.print(number); System.out.print(this.number); System.out.print(outSider.this.number); } }//创建实例public class Test{ public static void main(String[] args){ outSide out = new outSide(); outSide.innerSide inner = out.new innerSide(); //这是成员内部类生成实例的方式 inner.method(); // 输出 3 2 1 }} 特点:1.内部类 可以访问 外部类 的所有属性和方法 (实现原理:在内部类中生成一个引用外部类的this指针)。
当发生内外属性重名时,如果不指名是谁家的,将屏蔽外部属性。
2.外部类 若要访问 内部类的属性和方法,需要生成一个内部类的实例对象才行。
3.没有先生成外部类的实例对象的话,无法使用其中的内部类(原因:因为内部类构造器需要传入指向外部类实例对象的this指针)。
4.内部类好比外部类内的一个方法,可以用public、private、protected、default 和static 等修饰符修饰。
5.内部类 和 外部类 可分别继承不同的父类。
二、局部内部类
内部类放在在方法或一个作用域里。
class outSide{ private int number = 1; public void method{ int number = 2; class interSide{ public void print1(){ System.out.println(number); } interSide inter = new interSide(); inter.print1(); }}public class Test{ public static void main(String[] args){ outSide out = new outSide(); out.method(); //输出2 }} 特点:1.局部内部类有如局部变量,不能被public、private、protected、default 和 static 修饰。
2.局部内部类的方法只能访问局部final变量。
(因为传进内部类方法的参数生命周期可能比方法的生命周期短,为了解决这个问题,Java对可确定的参数采用拷贝,对不确定的参数采用内部类构造器初始化的方法来解决。
在这种解决办法下,如果对拷贝后的值进行修改,显然违背数据一致,因此将传进的参数要求为final,复制得到的也为final类型,都不可以改变)
三、匿名内部类
某个小小的类只在很固定的地方,如形式参数那边使用,就懒得规规矩矩写出一个类然后new对象,再把对象传进参数了。
现在就在固定的那个地方把类当场给写了,顺便new一个没名字的对象过去,连取名字都省了,nice。
interface example{ void realizeIt();}class oneClass{ public void method(example exam){ exam.realizeIt(); }}public class Test{ public static void main(String [] args){ oneClass one = new oneClass(); one.method(new example(){ @Override public void realizeIt(){ System.out.println("use only once"); } }); }} 特点:1.匿名内部类 和 局部内部类 一样,不能被public、private、protected、default 和 static 修饰。
2.匿名内部类 是 唯一 没有 构造器 的类,只能用其超类的构造器。(问题来了,上面代码用的构造方法名字是接口名诶,实际是转换成了Object类的构造方法)。
3.匿名内部类也只能访问局部final变量。
四、静态内部类
和成员内部类表面的差别就在于,静态内部类有static修饰符。
class outSide{ private int no = 1; private static int yes = 2; static class innerSide{ private int number = 3; public void method(){ System.out.println(outSide.this.no); // 编译失败,属性 no 不是 static 修饰的静态变量。 System.out.println(yes); //编译通过,输出 2 } }}public class Test{ public static void main(String[] args){ outSide.innerSide inner = new innerSide(); //or /* outSide.innerSide inner = new Outside.innerSide(); */ inner.method(); // 输出 2 }} 特点:1.静态内部类 不能 访问 外部内部类 的非静态成员变量和方法。
2.静态内部类的使用 不依赖于 外部类实例对象。