回顾《JAVA编程思想》第四版 第十章 内部类特点和实现JAVA“多重继承”
什么是内部类,匿名类,匿名接口,匿名方法?
内部类有什么特点?
内部类有哪些应用?
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();}}?
?
对于内部类,自己还是需要大量时间去使用,去体会。适时用,用的好。