什么是内部类,匿名类,匿名接口,匿名方法?
内部类有什么特点?
内部类有哪些应用?
JAVA语言是一个JAVA文件名对应一个类名称,在类作用域里面所定义的类就是内部类,它可以是静态,或是非静态的。而我们关注的大部分是非静态内部类。为什么要定义内部类呢?
从面向对象来讲,比如人有心脏,人被定义成类后,心脏是其身体必要的一部分,在设计时,我们可以把心脏定义成外部类,但是设计成内部类不是更加符合现实意义吗?是的。
对于现实世界中的场景抽象,很多都需要内部类的支持。当然这不仅仅是SUN公司设计出内部类的唯一用处,内部类最大的特点就是其不是单一存在,其还有一个外部对象的引用,在内部类中可以任意操作外部对象的属性和方法,包括private。我引用了《Think in Java》中的代码。
package thinkInJava; public class Outer { private int o_a = 10; public void print() { System.out.println(o_a); } public Inner newInner() { return new Inner(); } class Inner { private int i_b = 5; public Outer getOuter() { return Outer.this; } public void showstop() { System.out.println(o_a); } } public static void main(String args[]) { Outer outer = new Outer(); Inner inner = outer.newInner(); inner.getOuter().print(); inner.showstop(); } }
所以说脱离了外部对象,内部对象是不可能存在的(静态内部类除外)。同样代码附上。
package thinkInJava; public class Outer { private int o_a = 10; public void print() { System.out.println(o_a); } public Inner newInner() { return new Inner(); } static class Inner { private int i_b = 5; public void print(){ System.out.println(i_b); } public void haveATry() { i_b++; } } public static void main(String args[]) { Outer outer = new Outer(); Inner inner = outer.newInner(); inner.print(); inner.haveATry(); Outer.Inner inner1 = new Inner(); inner1.print(); Outer outer1 = new Outer(); Inner inner2 = outer1.newInner(); inner2.print(); } }
这里有一点,是Inner没办法用.this来获取外部类实例,
有一些注意点,一是非内部类中是不允许有内部变量、方法或类,即不允许定义静态内部成员
因为静态变量的作用就是让所有类对象共享一个状态,而这和内部类要依赖外部类对象存在产生矛盾。
内部类可以继承类或实现接口。典型的类子可以看一看HashMap,HashTable的源码,里面定义了Entry内部类,而且此内部类实现了Map.Entry的接口。
二是我们也应该关注到SUN引入内部类的又一优点,就是变相实现了JAVA多重继承,本身一个类是没办法继承多个类的,但是可以定义多个内部类,之后对内部类的一系列操作来实现这个特点。当然,你也可以用asm来实现JAVA多重继承。
public class Outer { class InnerA extends A { } class InnerB extends B { } ...... }
三是内部类下面还可以再定义内部类,理论上应该可以无限嵌套下去(这个没试过……)。
四是可以匿名定义类,接口。最相关的实例就是SWING中GUI的事件驱动模型,和声明各种监听器。
五是内部类/接口可以被继承/实现,但是初始化要同时关联到内部类的外部对象
package thinkInJava; class WithInner{ class Inner{} } public class Outer extends WithInner.Inner{ public Outer(WithInner wi){ wi.super(); } public static void main(String args[]) { WithInner wi = new WithInner(); Outer t = new Outer(wi); } }
六是内部类不可以被外部类的子类覆盖,二者是独立存在的。
package thinkInJava; public class Outer { class WithInner { class Inner { public void print() { System.out.println("super inner class"); } } } class InheritWithInner extends WithInner { class Inner { public void print() { System.out.println("child inner class"); } } public Inner newInner() { return new InheritWithInner.Inner(); } public WithInner.Inner newInner1() { return new WithInner.Inner(); } } public void test() { InheritWithInner tt = new InheritWithInner(); tt.newInner().print(); tt.newInner1().print(); } public static void main(String args[]) { Outer outer = new Outer(); outer.test(); } }
对于内部类,自己还是需要大量时间去使用,去体会。适时用,用的好。