本文参考"Thinking in java"的有关内容
1、源起
强化类间的逻辑关系或从属关系,比如将同类元素结合、将主类与工具类结合
2、优势
代码隐藏、与外围类通信、代码结构更加清晰
3、约束
内部类是紧紧依附于外部类对象的,也就是说没有一个已经实例化的外部类的对象,就无法实例化一个内部类对象,因此无法在外围类中定义static类型的内部类成员对象,但可以定义普通的内部类成员对象。典型误用:
package com.zjgtan.innerclasses; public class TestBed { public void f() { System.out.println("f()"); } public class Tester { public void foo() { TestBed t = new TestBed(); t.f(); } } public static Tester test = new Tester(); //这种语法是不行的,内部类紧紧的依附于外围类对象,实例化必须在外围类对象生成之后 }因此除了在非静态方法里,其他任意位置创建某个内部类对象,必须指明这个对象的类型:OuterClassName.InnerClassName
4、链接外部类
内部类拥有对其外围类所有成员的访问权,内部类对象只能在于外围类的对象相关联时才能被创建
4.1 .this与.new
通过.this返回外围类对象的引用,这是容易理解的,this本身就是对象的一个成员。
[类对象].new,在外部构造内部类对象时的语法,也体现了绑定性
.this语法
public class DotThis { void f() { System.out.println("DotThis.f()"); } public class Inner { public DotThis outer() { return DotThis.this; //返回当前外部类对象的引用 } } public Inner inner() { return new Inner(); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub DotThis dt = new DotThis(); DotThis.Inner dti = dt.inner(); //定义内部类对象,一定有相应的外部类对象 dti.outer().f(); //使用引用,调用成员函数 } }.new语法
public class DotNew {
public class Inner {
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner(); //.new语法,紧紧依附于外围类对象
}
}
5、匿名内部类
匿名内部类的重要应用,将返回值的生成与表示这个返回值的类的定义结合在一起
public class Parcel7 { public Contents contents() { return new Contents() { //内部类的定义 private int i = 11; @Override public int value() { // TODO Auto-generated method stub return i; } }; } public static void main(String[] args) { // TODO Auto-generated method stub Parcel7 p = new Parcel7(); Contents c = p.contents(); } }6、应用
6.1 工厂方法
鉴于工厂类和产品类逻辑上的从属关系,可以将它们组织到同一个类中
interface Service { //产品接口 void method1(); void method2(); } interface ServiceFactory { //工厂接口 Service getService(); } class Implementation1 implements Service { private Implementation1() { } public void method1() { System.out.println("Implementation1 method1"); } public void method2() { System.out.println("Implementation1 method2"); } //构造工厂 public static ServiceFactory factory = new ServiceFactory() { //将匿名内部类作为成员对象,工厂模式 @Override public Service getService() { // TODO Auto-generated method stub return new Implementation1(); } }; } class Implementation2 implements Service { private Implementation2() { } public void method1() { System.out.println("Implementation2 method1"); } public void method2() { System.out.println("Implementation2 method2"); } //构造工厂 public static ServiceFactory factory = new ServiceFactory() { @Override public Service getService() { // TODO Auto-generated method stub return new Implementation2(); } }; } public class Factories { public static void ServiceConsumer(ServiceFactory fact) { //客户端程序 Service s = fact.getService(); s.method1(); s.method2(); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ServiceConsumer(Implementation1.factory); ServiceConsumer(Implementation2.factory); } }由上述实例可以看出,在客户端程序中,完全屏蔽了产品到底有多少种,将到底实例化哪个具体产品延迟到了运行期,实现了产品特性的模板化更新。
6.2迭代器模式
interface Selector { //迭代器接口,规定了迭代器的基本接口 boolean end(); Object current(); void next(); } public class Sequence { private Object[] items; private int next = 0; public Sequence(int size) { items = new Object[size]; } public void add(Object x) { if (next < items.length) { items[next++] = x; } } private class SequenceSelector implements Selector { //内部类的具体迭代器 private int i = 0; public boolean end() { return i == items.length; } public Object current() { return items[i]; } public void next() { if (i < items.length) i++; } } public Selector selector() { //返回迭代器 return new SequenceSelector(); } public static void main(String[] args) { // TODO Auto-generated method stub Sequence sequence = new Sequence(10); for (int i = 0; i < 10; i++) { sequence.add(Integer.toString(i)); } Selector selector = sequence.selector(); while (!selector.end()) { System.out.print(selector.current() + " "); selector.next(); } } }将迭代器与具体类绑定,通过动态方法返回。
3、内部类与控制框架
模板方法、应用程序框架、命令设计模式