从一个简单的计时器,看Java接口的作用
2014-04-27 16:26
387 查看
作为一个Java初学者来说,应该很难理解 interface 的作用,明明是个没有实现任何功能的东西,在API中却有那么多的接口类型,下面我将会用一个很小的计时器例子来简单展示下 interface 作用。
类库很简单,只有三个元素,类图如下:
Timer:是个计时器
ExecutionThread:是在计时器内使用的线程
ITask:即为计时器要执行的任务,而UserTask将会是用户为了给计时器指派任务而实现的接口
ITask 接口源码
package individual.hcx.generictimer; /** * 通用计时器的任务接口,为计时器指派任务,只需实现此接口中的task(),并用实现类初始化计时器即可 * @author hcx * */ public interface ITask { void task(); }
该接口很简单,只有一个方法需要实现,但该接口非常重要,后面会详细解释。
ExecutionThread源码
package individual.hcx.generictimer; public class ExecutionThread extends Thread { //线程休眠事件 private long period; ITask task = null; private boolean isRun = true; /** * 创建一个线程休眠事件为 period 毫秒的线程 * @param period * @param task */ public ExecutionThread(long period , ITask task) { this.period = period; this.task = task; } /** * 结束线程执行 */ public void stopTask() { this.isRun = false; } public void run() { try { while(isRun) { //执行 task.task(); //当前线程休眠 Thread.sleep(period); } } catch(Exception ex) { ex.printStackTrace(); } } }
该线程类的实现也很容易看懂,其中加了一个状态字,以控制线程的终止。
在这个执行线程中,最为重要的就是在run()方法中执行的task.task();这其实就是面向接口编程的一种方式,准确来说,在编写ExecutionThread代码的时候,我们仅仅只知道一个抽象的方法,但是我们却能够调用它。在ExecutionThread中我们其实并不关心task的具体实现,我们只要知道他有这样的方法就行了,这就是抽象的具体应用。
Timer的源码
package individual.hcx.generictimer; public class Timer { long period = 0; ExecutionThread executionThread = null; /** * 使用计时器的执行间隔初始化一个计时器 * @param period 执行间隔,以毫秒为单位,该值最小为1,如果传入小于1的值将还会是1 * @param task 计时器中执行的任务 */ public Timer(long period , ITask task) { if(period <= 0) this.period = 1; else this.period = period; this.executionThread = new ExecutionThread(period, task); } /** * 开始计时器,该方法只能调用一次 */ public void start() { this.executionThread.start(); } /** * 结束计时器,一旦结束将无法重启,该方法只能调用一次 */ public void stop() { this.executionThread.stopTask(); } }
这段代码是Timer的主体实现,它定义了两个行为,start和stop,用于开始和结束计时器。Timer的构造器是需要一个ITask对象来初始化的,在这里我们还是不需要关心ITask的实现。
至此,其实我们的类库已经开发完毕,这个时候完全可以把我们的代码编译打包,生成一个Jar给别人使用,那别人如何使用呢?这里我写了一个场景类来模拟。
package individual.hcx.generictimer; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub Timer timer = new Timer(1000 , new MyTask()); timer.start(); } } class MyTask implements ITask { int time = 1; public void task() { // TODO Auto-generated method stub System.out.println(time); time ++; } }
首先,我们需要实现一个ITask的实现类,在这个实现类中我们需要给计时器指派任务,也就是实现task()方法,我的实现很简单,只是输出一个数字。有了ITask的实现类,我们可以通过这个实现类实例化一个Timer对象,然后将它启动,这个时候你会发现,计时器可以很好的工作。当然啦,你完全可以再ITask的实现类中实现更复杂的方法,甚至说,你可以创建更多的ITask的实现类,然后来实例化更多的Timer对象,而这个时候你可以完全不用关心Timer的内部结构!
那么,interface 在这个程序中到底起了什么作用呢?功能隔离和编码分工!
计时器的功能是,能够以一定的周期执行某个特定的任务,一定的周期我们可以用一个long的变量来指定,但是特定的任务我们怎么处理呢?没错,就是用 interface 来抽象。于是,计时器的功能与具体的任务充分隔离开来了,既然功能隔离了,那么编码自然就可以分工了。负责编写计时器的的人,可以完全只去考虑计时器部分的实现。而实现指定任务的人,可以完全只去考虑任务的设计。只要这两拨人,遵循这个接口,那么在Client这样的高层结构中就能很好的集成,以完成一个复杂系统的开发。
最后,这个简单的计时器,其实可以理解为一个非常简单的框架,它通过接口来约束,客户在框架中的行为。当然啦,在实际中比较成功的框架,不仅仅只有接口这一个约束,但接口在任何一个框架中都是大量存在的!
相关文章推荐
- java中接口的作用
- Hbase简单的java接口
- 简单理解遵循接口隔离原则的Java设计模式编程
- java中接口的作用
- Java回顾:用一个Demo来说明继承抽象类和实现接口的简单框架模型
- java中抽象类和接口的作用与区别
- java后台设计简单的json数据接口,设置可跨域访问,前端ajax获取json数据
- java中的Serializable接口的作用
- Java 简单的接口实现
- Java之接口及其作用
- java中的Serializable接口的作用
- 关于javaComparable和Comparator接口详解(简单的小例子)
- java中final的作用及简单介绍
- 使用Java8的函数式接口@FunctionalInterface实现简单异步调用
- java接口作用及其好处
- Java里的接口的interface 简单介绍.
- 实例讲解Java中的接口的作用
- java中的接口Serializable的作用和例子
- java接口作用(2)
- Java WebService 简单实例 方式三(axis1接口调用方式)