从外部类的非静态方法之外的任意位置创建某个内部类的对象,均需要指明对象类型:OuterClass.InnerClass,可通过函数或者是outer.new InnerClass()实例化(outer是外部类的一个实例化对象)。
内部类拥有对其外部类所有成员的访问权:当某个外围类的对象创建一个内部类对象时,内部类获得一个指向外围类对象的引用,下面代码可以验证:
public class Outer { class Inner { Outer getOuter() { return Outer.this; // 指向外围类对象的引用 } } public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); System.out.println(outer.hashCode()); System.out.println(inner.getOuter().hashCode()); } } /* output 12677476 12677476 */
匿名内部类:
public class Test { public Class getClass(final int i) { // 因为参数i在内部类中需要使用,需要声明为final类型 return new Class(i) { // 添加属性或方法 // 对于匿名类而言,此初始化的效果就是构造器,但无法实现构造器重构 { System.out.println(i); } }; // 与上面等价 // class TT extends Class { // TT(int i) { // super(i); // } // // 添加属性或方法 // } // return new TT(i); } public Interface getInterface() { return new Interface() { @Override public void f() { } // other code }; // 与上面等价 // class TT implements Interface { // @Override // public void f() { // } // // other code // } // return new TT(); } public static void main(String[] args) { } } class Class { private int i = 1; Class(int i) { this.i = i; } public void f() { System.out.println("other f" + i); } } interface Interface { int i = 3; void f(); }
嵌套类:
如果不需要内部类对象与外部类对象之间有联系,那可将内部类声明为static :
则1、创建嵌套类的对象不需要外围类对象,2、不能从嵌套类的对象中访问非静态的外围类对象
嵌套类可以有static数据和字段,也能包含嵌套类
为什么需要内部类:
Q :如果只是需要一个对接口的引用,为什么不通过外围类实现接口呢?
A:如果这能满足需求,那就应该这么做!
每个内部类都能独立地继承自一个(接口的)实现,无论外围类是否已经继承了某个(接口的)实现。通过内部类可以实现多重继承
闭包与回调:
内部类实现一个接口, 通过回调返回接口的一个引用,该引用指向内部类的一个对象,外界只能操作接口提供的方法,内部类对外是透明的。
当内部类被继承时,指向外围类对象的引用必须被初始化,而在到处类中不再存在可连接的默认对象,所以在构造器内使用如下语法:enclosingClassReference.super();
当导出类中重新定义了与基类的内部类同名的内部类,基类的内部类将被覆盖吗?事实证明,这两个内部类是完全独立的两个实体,除非是明确继承。
局部内部类:在代码块中创建,但不能有访问说明符,因为它不是外围类的一部分,但它可以访问房前代码块内的常量,以及外围类的所有成员。
内部类的class文件名为:OuterClass$InnerClass.class