体现:当A类中的内容要被B类直接访问,而 A类也需要创建B的对象去访问B的内容时,可以将B类定义到A类的内部,这样访问更为便捷。将B称之为匿名内部类。
#看一个类是否需要直接访问另一个类,若需要,直接定义成另一个类的内部类。
一个类的成员都是被对象调用、访问。
而内部类作为成员,应该先有外部类对象,再有内部类对象。
例如在调用一内部类方法show时:
Outer.Inner in = new Outer().new Inner();
in.show();
内部类被访问的方式:
情况一:内部类在成员位置上的被访问方式。
成员是可以被指定的修饰符所修饰的。
public :不多见,因为更多的时候,内部类已经被封装到了外部类中,不直接对外提供。
static :(静态只能访问静态)且静态方法/类 随着类的加载而加载。
对静态内部类中的非静态成员show进行调用:
因为内部类是静态的,所以不需要创建outer的对象,直接创建内部类对象就可以了。
Ouer.Inner in = new Outer.Inner();
in.show();
如果静态内部类有静态成员,该如何访问呢?
既然静态内部类已经随着外部类加载而加载,而且静态成员随着类的加载而加载,那么就不需要对象,直接用类名调用即可。
Outer.Inner.staticshow();
#非静态内部类中不允许定义静态成员,仅允许在非静态内部类中定义静态常量。static final XXX;
如果想要在内部类定义静态成员,必须内部类也要被静态修饰符修饰。
★内部类被静态修饰以后,随着外部类的加载而加载,可以把一个静态内部类理解为就是一个外部类。(静态中无this)
能被static修饰的类,只可能是定义在成员位置上的内部类。
情况二:内部类在局部位置时。
内部类其实也可以定义在外部类的局部位置上。
内部类定义在局部时,只能访问被final修饰的局部变量,因为编译生成的class中操作的直接是最终的那个数值了。
为什么不能访问非最终的局部变量呢?
因为局部变量的生命周期太短了。
为什么内部类就能直接访问外部类中的成员呢?
那是因为内部类其实持有了外部类的引用 外部类.this
对于静态内部类不持有 外部类.this 而是直接使用 外部类名.xxxx();
内部类的延伸:
内部类是可以继承或者实现外部其他的类或者接口的。
好处:
可以通过内部类的方式对类进行继承重写,或者接口进行实现。
可以通过公共的方式对其内部类对象进行访问,因为通常内部类很有可能被外部类封装其中。
我就可以通过父类或者接口的方式访问到内部类对象。
匿名内部类:其实就是一个带有内容的子类对象。
匿名内部类核心就是子对象。
格式:new 父类 or 接口 (){子类的内容}
匿名内部类就是内部类的简化形式。
#匿名内部类有前提,内部类必须要继承父类或者实现接口。(且若方法过多,不宜写简化形式。【一般父类方法超过两个就不建议写匿名内部类。】)
不想创建具体的子类型,还想创建AbsDemo的子类对象,如何实现? 没有子类型,直接使用父类型。
可若父类是抽象类,怎么可以new对象呢?
ps:抽象类之所以不能new对象是因为抽象方法没重写,所以只需重写其方法就可以了。
例如父类:
abstract class AbsDemo{ abstract void show(); }
在其他类的方法中被调用时
public void method(){ //这种写法称为:匿名内部类 new AbsDemo(){ //重写show方法 void show(){ system.out.println("num=="+num); } }.show(); }
若有两个show方法在AbsDemo中,则可:
public void method(){ //这种写法称为:匿名内部类 AbsDemo in = new AbsDemo(){ public void show1(){} public void show2(){} }; in.show1(); in.show2(); }
★ new 某类名(); //创建的是某类对象。
new 某类名(){}; //创建的是某类的子类对象。