博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么需要内部类
阅读量:6179 次
发布时间:2019-06-21

本文共 6857 字,大约阅读时间需要 22 分钟。

hot3.png

一、闭包与回调

    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 List
events = 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、控制框架使用居多

转载于:https://my.oschina.net/Howard2016/blog/1620408

你可能感兴趣的文章
mv或者cp带小括号文件名解析问题总结
查看>>
Elasticsearch学习笔记3: bulk批量处理
查看>>
EBS12.2.5 升级到EBS12.2.6的问题及跟踪处理
查看>>
网站访问流程
查看>>
java的日志工具log4j的配置方法
查看>>
jQuery on()方法
查看>>
步调一致才能得胜利
查看>>
mysql 锁机制
查看>>
add_header X-Frame-Options "SAMEORIGIN";NGINX
查看>>
linux中的计划任务
查看>>
Android style报错
查看>>
Lintcode130 Heapify solution 题解
查看>>
【Map】Map、HashMap
查看>>
解决纯数字字符串在js方法参数中不稳定或被截取的问题
查看>>
如何在VMware安装Windows系统
查看>>
阶段性理解phantomjs/selenium/casperjs
查看>>
Java中高级开发工程师是什么技术水平(附28套Java进阶+高级视频教程)
查看>>
sudo命令
查看>>
第十九章 文本处理流编辑器:awk编程
查看>>
Xtrabackup+Rsync 备份数据库并同步到远端备份机
查看>>