为什么使用内部类?
每个内部类都能独立地继承自一个(接口的)实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类没有影响。
- 成员内部类
- 内部类对于外部类来说,相当于一个成员变量。内部类可以使用任意访问控制符
- 内部类的方法可以直接访问外部类的数据,而不受访问控制符的影响
- 创建内部类对象方法:内部类 对象名 = 外部类对象.new 内部类()
- 编译之后产生两个class文件:Outer.class 和 Outer$Inner.class
- 内部类中不能存在任何static的变量和方法
- 为啥?因为静态变量和方法不依赖对象,仅与类有关。在加载静态域时,根本没有外部类。所以在非静态内部类中不能定义static变量和方法,编译会不通过。
- 静态内部类:用static修饰的内部类
- 静态内部类访问外部类的非静态成员:不能直接访问,需要 new 外部类().成员
- 如果访问外部类的static成员(名称与内部类相同):“类名.静态成员”
- 如果访问外部类的static成员(名称与内部类不相同):"静态成员名"
- 创建静态内部类对象(不需要外部类对象):内部类 对象名 = new 内部类()
- 方法内部类:访问仅限与方法内(或者该作用域内)
- 局部内部类就像方法里的局部变量一样,不能用public protected private static修饰的
- 只能访问方法中定义的final类型的局部变量。**原因:**局部变量会随着方法体执行完而消亡。但内部类对象还存在。(导致内部类要访问一个不存在的局部变量)(使用final不会会保持对象的引用,还会让编译器持续维护这个对象在回调方法中的生命周期)(局部内部类并不是直接调用方法传进来的参数,而是内部类通过构造器将参数备份一份)
- 匿名内部类
- 匿名内部类直接使用 new 来生成一个对象的引用
- 缺点:仅能被使用一次
- 使用匿名内部类必须继承一个类或者实现一个接口(两者不可兼得)
- 匿名内部类不能有构造函数,不能存在任何静态成员变量和静态方法
- 匿名内部类不能是抽象的必须实现继承的类或者实现的接口的所有抽象方法
- 匿名内部列初始化:使用构造代码块。使用构造代码块能够达到为匿名内部类创建一个构造器的效果。