一、闭包与回调
1、通过内部类实现多重继承(常用的接口多重继承也可以实现)(基于接口)
package com.lh.innerclass.class5;/**** * * 对接口 * 通过内部类实现多重继承(常用的接口多重继承也可以实现) * * @author Liu * */interface A{};interface B{};class X implements A,B{}class Y implements A{ B makeB(){ return new B(){}; }}public class MultiInterfaces { static void takeA(A a){} static void takeB(B b){} public static void main(String[] args) { X x = new X(); Y y = new Y(); /*************下面两种效果一样****************/ takeA(x); takeA(y); takeB(x); takeB(y.makeB()); }}
2、通过内部类实现多重继承,更加灵活(对非接口,如实现类、抽象类)
package com.lh.innerclass.class5;/*** * 对非接口,如实现类、抽象类 * 通过内部类实现多重继承,更加灵活 * * @author Liu * */class D{}abstract class E{}class Z extends D{ E makeE(){ return new E(){}; }}public class MultiImplementation { static void takeD(D d){} static void takeE(E e){} public static void main(String[] args) { Z z = new Z(); takeD(z); takeE(z.makeE()); }}
3、内部类的闭包与回调
package com.lh.innerclass.class5.first;/*** * * 内部类的闭包与回调 * * * @author Liu * */interface Incrementable{ void increment();}class Callee1 implements Incrementable{ private int i = 0; public void increment() { i++; System.out.println(i); } }class MyIncrement{ public void increment() { System.out.println("Other operation"); } public static void f(MyIncrement mi){ mi.increment(); }}class Callee2 extends MyIncrement{ private int i=0; public void increment() { super.increment(); i++; System.out.println(i); } //这里是通过内部类的方式实现多重继承(一个具体的类,一个接口) private class Closure implements Incrementable{ //调用外围类的方法 public void increment() { Callee2.this.increment(); } } //提供私有内部类一个创建实例的引用 Incrementable getCallbackReference(){ return new Closure(); }}class Caller{ private Incrementable callBackReference; Caller(Incrementable cbh){ this.callBackReference = cbh; } void go(){ this.callBackReference.increment(); }}public class Callbacks { public static void main(String[] args) { Callee1 c1 = new Callee1(); Callee2 c2 = new Callee2(); MyIncrement.f(c2); Caller caller1 = new Caller(c1); Caller caller2 = new Caller(c2.getCallbackReference()); caller1.go(); caller1.go(); caller2.go(); caller2.go(); }}
二、内部类与控制框架
内部类大量运用于事件驱动类场合(如GUI:图形用户界面/java swing库)
1、Controller.java
package com.lh.innerclass.class5.second;import java.util.ArrayList;import java.util.List;public class Controller { private Listevents = new ArrayList<>(); public void addEvent(Event e){ events.add(e); } public void run(){ while(this.events.size() > 0){// for(Event event : events){ //为避免java.util.ConcurrentModificationException异常 for(Event event : new ArrayList<>(events)){ if(event.ready()){ System.out.println(event); event.action(); events.remove(event); } } } } public List getEvents() { return events; } }
2、Event.java
package com.lh.innerclass.class5.second;/**** * * 内部类大量运用于事件驱动类场合(如GUI:图形用户界面/java swing库) * * @author Liu * */public abstract class Event { private long eventTime; //不允许改变的延迟时间 protected final long delayTime; public Event(long delayTime) { this.delayTime = delayTime; start(); } public void start() {// this.eventTime = System.currentTimeMillis() + delayTime; this.eventTime = System.nanoTime() + delayTime; } public boolean ready() {// return System.currentTimeMillis() >= this.eventTime; return System.nanoTime() >= this.eventTime; } abstract void action();}
3、GreenHouseController.java
package com.lh.innerclass.class5.second;/*** * * 内部类可以调用外围类的任何数据,包括任何字段和方法,避免代码写得笨拙 * 控制框架使用居多 * * @author Liu * */public class GreenHouseController { public static void main(String[] args) { GreenHouseControls gc = new GreenHouseControls(); gc.addEvent(gc.new Bell(900)); Event[] events = { gc.new ThermostatNight(0), gc.new LightOn(200), gc.new LightOff(400), gc.new WaterOn(600), gc.new WaterOff(800), gc.new ThermostatDay(1400) }; gc.addEvent(gc.new Restart(2000, events)); //静态内部类调用方法 gc.addEvent(new GreenHouseControls.Terminate(new Integer(5000))); gc.run(); }}
4、GreenHouseControls.java
package com.lh.innerclass.class5.second;/*** * * 温室控制器例子 * * @author Liu * */public class GreenHouseControls extends Controller{ //灯光 private boolean light = false; //水 private boolean water = false; //温度调节器开关 private String thermostat = "Day"; public class LightOn extends Event{ public LightOn(long delayTime) { super(delayTime); } public void action(){ light = true; } public String toString(){ return "Light is on!"; } } public class LightOff extends Event{ public LightOff(long delayTime) { super(delayTime); } public void action(){ light = false; } public String toString(){ return "Light is off!"; } } public class WaterOn extends Event{ public WaterOn(long delayTime) { super(delayTime); } public void action(){ water = true; } public String toString(){ return "Greenhouse Water is on!"; } } public class WaterOff extends Event{ public WaterOff(long delayTime) { super(delayTime); } public void action(){ water = false; } public String toString(){ return "Greenhouse Water is off!"; } } public class ThermostatDay extends Event{ public ThermostatDay(long delayTime) { super(delayTime); } public void action(){ thermostat = "Day"; } public String toString(){ return "Thermostat on Day setting!"; } } public class ThermostatNight extends Event{ public ThermostatNight(long delayTime) { super(delayTime); } public void action(){ thermostat = "Night"; } public String toString(){ return "Thermostat on Night setting!"; } } //到达时间响铃 public class Bell extends Event{ public Bell(long delayTime) { super(delayTime); } public void action(){ addEvent(new Bell(delayTime)); } public String toString(){ return "Bing!"; } } //重启系统 public class Restart extends Event{ //第一次调用该构造方法时执行 public Restart(long delayTime,Event[] events) { super(delayTime); this.events = events; //这里打印1,表示目前只有1个任务 System.err.println(GreenHouseControls.this.getEvents().size()); for(Event event : events){ addEvent(event); } } private Event[] events; public void action(){ for(Event event : this.events){ //重新赋予新的目标时间 event.start(); addEvent(event); } //这里相当于构造方法本身,重复执行循环... //重新赋予新的目标时间 start(); addEvent(this); } public String toString(){ return "Restarting system!"; } } public static class Terminate extends Event{ public Terminate(long delayTime) { super(delayTime); } @Override void action() { System.exit(0); } public String toString(){ return "Terminate!"; } }}
输出结果:
Bing!Thermostat on Night setting!Light is on!Light is off!Greenhouse Water is on!Greenhouse Water is off!Thermostat on Day setting!Restarting system!Terminate!
小结:
1、内部类可以调用外围类的任何数据,包括任何字段和方法,避免代码写得笨拙
2、控制框架使用居多